hdu 1565 方格取数(1)(DP 状态压缩)
方格取数(1)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2585 Accepted Submission(s): 976
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
3 75 15 21 75 15 28 34 70 5
188
思路:状态压缩DP,记录从上个状态到下个状态。枚举每个状态,找到匹配的合法状态。
令我很惊讶的是这代码居然只跑了468MS,怎么可能???我自己出了组20 接下来是20x20 的都是1的矩阵在电脑上跑半天都没出来。居然还能AC、
真不知道杭电的这题数据有多弱啊。
大家跑跑这组数据看看要多久。
20
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int dp[2][28659]; int low[28659],pos; int n; int map[33]; void ini() { pos=0; for(int i=0;i<1<<n;i++) if(!(i&(i<<1))) low[pos++]=i; } int get(int x) { int ret=0,t=0; while(x) { if(x&1)ret+=map[t]; t++;x>>=1; } return ret; } int main() { ///cout<<(1<<22)<<endl; while(cin>>n) { memset(dp,0,sizeof(dp)); int v=0,_max=0; ini(); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) cin>>map[j]; /*if(!i) { for(int j=0;j<pos;j++) dp[v][low[j]]=get(low[j]); } else {*/ for(int j=0;j<pos;j++) { int ma=0; for(int k=0;k<pos;k++) { if(low[j]&low[k])continue; if(ma<dp[v^1][k]) ma=dp[v^1][k]; } dp[v][j]=ma+get(low[j]); _max=max(_max,dp[v][j]); }v^=1; // } } cout<<_max<<"\n"; } }