坑爹的题目。不过不能说不是一道挺好的题目。

坑主要坑在,妹的我一样的复杂度,写的姿势略差了点然后就一直超时。

比赛的时候我还直接就看错题目,把AND运算看成了OR。。。还敲完交了一发。

这题很容易想到:

因为给出的数字只有13位,所以每位用2位二进制表示。

如:

00 1的个数为偶数,最后的结果为0

01 1的个数为奇数,最后的结果为0

10 1的个数为偶数,最后的结果为1

11 1的个数为奇数,最后的结果为1

这样就可以转移求出最后的结果。然而这样做的复杂度是O(50*2^26)>1e9. 肯定不行。

仔细想想我们可以发现,当出现了0以后结果一定为0。这样用2位二进制位表示这个信息有些多余了。我们可以用三进制0,1,2和多余附加的一个标志位来表示这种信息。

如果某一位一直都是1则用0表示,如果出现了0,则用1,2分别代表出现奇数个1和偶数个1。 再配上附加的标志位来记录当前为止已加入数个数的奇偶性。分析下就可以发现,这样是能够把每一种情况表示出来的。

原先得用2^26=67108864种状态表示,现在只需要2*3^13=3188646. 直接就相差了20倍。wonderful!

然后剩下来还有一个关键问题,怎样将转移的O(13)->O(1)

PS:我原先的思想是,预处理,对于2*3^13的每种状态对应2^26某一种。结果一直TLE,这种做法会有比较大的内存消耗,而且预处理时间也较长。

可以预处理7位的所有情况,也就是把13位分成两半,因为对这两半的操作都是一样的,所以只需要预处理一半就行了,然后空间消耗变得非常小,转移操作变成O(1).

Rikka with Sequence

时间限制:20000ms
单点时限:2000ms
内存限制:512MB

描述

众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

勇太有n个[0,8192)中的整数,现在六花可以从中选出若干个数(不可以不取),她的方案需要满足她选出的所有数的异或和恰好等于它们AND(二进制与运算)起来的值,现在勇太想让六花求出满足条件的方案数。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?

输入

第一行一个整数n,接下来一行里n个整数。

1<=n<=50

输出

输出一行表示答案。

样例输入
3
1 1 1
样例输出
4
//
//  main.cpp
//  hiho19
//
//  Created by 陈加寿 on 16/3/20.
//  Copyright © 2016年 chenhuan001. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <time.h>
#include <math.h>
#include <algorithm>
using namespace std;#define K 8200int g[55];
long long dp[2][1600000][2];
int chg[2200][130][2];
int chg1[2200][130][2];void init()
{int save[15];memset(save,0,sizeof(save));for(int i=0;i<2187;i++){for(int j=0;j<(1<<7);j++){for(int p=0;p<2;p++){//然后你想怎么搞就怎么搞吧。int tmp1=0,tmp2=0;for(int k=0;k<7;k++){if(save[k] == 0){tmp1 |= (1<<k);}}for(int k=0;k<7;k++){if(save[k] == 0){if(p) tmp2|=(1<<k);}else if(save[k] == 1) tmp2|=(1<<k);}tmp1 &= j;tmp2 ^= j;//然后再转变回去。int tmp=1;int sum=0;for(int k=0;k<7;k++){if( (tmp1&(1<<k))!= 0){;}else if( (tmp2&(1<<k))!= 0 ){sum += tmp;}else if( (tmp2&(1<<k))== 0 ){sum += 2*tmp;}tmp *=3;}chg[i][j][p] = sum;chg1[i][j][p] = (chg[i][j][p]/3)*2187;}}int tj=0;save[tj]++;while(save[tj]>=3){save[tj+1]++;save[tj]=0;tj++;}}
}//是与运算
//clock_t be,ed;
//void checktime()
//{
//    ed=clock();
//    cout<<(double)(ed-be)/CLOCKS_PER_SEC<<endl;
//    be=clock();
//
//}
int main() {//看错题目??? 不思考看题解??? 你是SB吗int n;cin>>n;// 我真是日了狗了for(int i=0;i<n;i++){scanf("%d",g+i);//13 = 1594323(nn,13);//1594323 = 1594323(1594323,tcnt);
    }//    if(13 == 0)//    {//        cout<<((1LL)<<n)-1<<endl;//        return 0;//    }//be=clock();
    init();//checktime();int a=0;memset(dp,0,sizeof(dp));dp[a][0][0] = 1;for(int i=0;i<n;i++){memset(dp[a^1],0,sizeof(dp[a^1]));int up=g[i]>>6;//这个应该是移6位吧int down = g[i]&((1<<7)-1);int j1=0,j2=0;for(int j=0;j<1594323;j++){j2= j/729; j1=j%2187;for(int p=0;p<2;p++){//dp[a^1][j] += dp[a][j];int sum=0;if(dp[a][j][p] != 0){dp[a^1][j][p] += dp[a][j][p];sum = chg1[j2][up][p]+chg[j1][down][p];dp[a^1][sum][p^1] += dp[a][j][p];}}
//            j2++;
//            if(j2>=(2187))
//            {
//                j2=0;j1++;
//            }
        }a = a^1;}//checktime();long long ans=0;int save[15];memset(save, 0, sizeof(save));for(int j=0;j<1594323;j++){for(int p=0;p<2;p++){int flag=0;for(int k=0;k<13;k++)if(save[k]==1){flag=1;break;}else if(save[k]==0 && p==0){flag=1;break;}if(flag==0) ans += dp[a][j][p];}int tj=0;save[tj]++;while(save[tj]>=3){save[tj+1]++;save[tj]=0;tj++;}}//checktime();
    cout<<ans<<endl;return 0;
}

转载于:https://www.cnblogs.com/chenhuan001/p/5305845.html

hihocoder 1279(状压)相关推荐

  1. 洛谷P1896 [SCOI2005]互不侵犯 状压dp+位运算

    题目链接:https://www.luogu.org/problem/P1896 题意:n*n的格子填数,每个数填放位置的周围(8个)不能有其他的数 n<=9 ,矩形状压 f[i][j][s], ...

  2. POJ 1038 Bugs Integrated Inc (复杂的状压DP)

    \(POJ~1038~~*Bugs~Integrated~Inc:\) (复杂的状压DP) \(solution:\) 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前那道炮兵阵地 ...

  3. codeforces 8C. Looking for Order 状压dp

    题目链接 给n个物品的坐标, 和一个包裹的位置, 包裹不能移动. 每次最多可以拿两个物品, 然后将它们放到包里, 求将所有物品放到包里所需走的最小路程. 直接状压dp就好了. #include < ...

  4. UVA10296 Jogging Trails(中国邮递员问题)(欧拉回路、一般图最大权匹配 / 状压DP)

    整理的算法模板合集: ACM模板 目录 思路 UVA10296 Jogging Trails 题目翻译: 给你n个点,m条无向边,每条边有一定的距离数值,构造成一个连通图.问从任意一点出发,遍历所有的 ...

  5. POJ 2411 Mondriaan‘s Dream(最清楚好懂的状压DP讲解)(连通性状态压缩DP)

    poj 2411 Mondriaan's Dream(最清晰的状压DP解析) 闫氏DP大法好 我们这里是一列一列地来,因为是一个棋盘性的状态压缩DP,从哪个方向都一样 摆放的小方格总方案数 等价于 横 ...

  6. 【每日DP】day2、P1879 [USACO06NOV]Corn Fields G玉米地(状压DP模板题)难度⭐⭐⭐★

    昨天的每日DP我还在写01背包,今天就到状压DP了,真刺激. P1879 [USACO06NOV]Corn Fields G 题目链接 输入 2 3 1 1 1 0 1 0 输出 9 一道简单的状压D ...

  7. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

  8. 【洛谷 P1896】[SCOI2005]互不侵犯(状压dp)

    题目链接 题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 这是道状压\(DP\)好题啊.. ...

  9. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

  10. Codeforces-868C. Qualification Rounds(状压)

    传送门 N题K人,给出N行K列数据,aij为1代表i题被第j个人所了解.求是否能找出一套题(在这N题中找任意题)使得每个人了解的题不超过这套题数目的一半.(1 ≤ n ≤ 105, 1 ≤ k ≤ 4 ...

最新文章

  1. C#异步编程模式IAsyncResult概述
  2. azure container 的命名规则
  3. IO流(文本文件读取练习)
  4. 2596 售货员的难题
  5. linux-2.6.32在mini2440开发板上移植(16)之LED 驱动程序移植
  6. 转: ImageMagick 命令行的图片处理工具(客户端与服务器均可用)
  7. 怎样设置电脑壁纸_谷歌地球实时壁纸,电脑和手机实现方案都在这里了
  8. 开源软件的总拥有成本指南
  9. python3简单爬取妹纸图网站图片
  10. 想学制作外挂的新手看过来
  11. mac m1使用免费的hopper demo版本和machoView破解修改iphone上的app
  12. 微信公众号教程(3)微信公众平台群发消息
  13. Java语言基础知识(一)
  14. Hack The Box - Starting Point - TIER 0
  15. gorilla/mux类库解析
  16. 【可视化大屏】屏幕多分辨率适配方案
  17. OPERA更改房间类型(维护里)
  18. Redis 内存快照:宕机后,Redis如何实现快速恢复?
  19. Ubuntu18.04启动memtest86
  20. 获3500万美元A轮融资,滴普科技用数字智能加速企业升级

热门文章

  1. 质检总局要求:做好口岸核与辐射物质监测工作
  2. 为什么要做SMT贴片加工
  3. 全球与中国远程监考解决方案市场深度研究分析报告
  4. HCIE认证培训 华为AAA认证详解-ielab
  5. Disasters_on_social_media
  6. 中望CAD的引线标注格式怎么改_10年工作经验的CAD大师教你如何快速标注!
  7. poi追加写EXCEL文件
  8. ZeroBlog翻译
  9. 软考考完了,怎么评职称呢?
  10. 文件排序工具sort