hdu1565 方格取数 状压dp
这道题我wa了一下午一晚上
我没看到多组样例!
哦对了初始化的时候是1移位 计算和的时候取位数判断是否为1;
心态爆炸 你说我写错了也好啊 。。。
好吧好吧再接再厉55555555555555
方格取数(1)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10629 Accepted Submission(s): 3999
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3
75 15 21
75 15 28
34 70 5
Sample Output
188
Author
ailyanlu
Source
Recommend
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int mapp[21][21]; int N,top; int dp[25][18000],num[25][18000]; int state[18000]; void init0(){ int maxn = 1<<N; for(int i = 0;i < maxn;i++){ if(!(i&(i<<1)))//修改 state[++top] = i; } } void init() { top=0; int i; int total=1<<N; for(i=0;i<total;i++) { if((i&i<<1)) continue; state[++top]=i; } } int fit(int x,int k){// cm是行 cn是状态数 int sum = 0; for(int i = 1;i <= N;i++){ if((x >> (i-1))&1) //修改 sum += mapp[k][i]; } return sum; } int main(){ while(scanf("%d",&N) != EOF){ int i,j,k,z; memset(dp,0,sizeof(dp)); for(i = 1;i <= N;i++){//输入地图 for(j = 1;j <= N;j++){ scanf("%d",&mapp[i][j]); } } init(); // for(i = 1;i <= top;i++){//计算每一行每种状态的总值 dp[1][i] = num[1][i] = fit(state[i],1); for(j = 2;j <= N;j++){ num[j][i] = fit(state[i],j); } } for(i = 2;i <= N;i++){//枚举1~n-1行 for(j = 1;j <= top;j++){//枚举当前行状态 for(k = 1;k <= top;k++){//枚举上一行状态 if(state[j]&state[k])//是否有格子共用一条边 continue; dp[i][j] = max(dp[i][j],dp[i-1][k] + num[i][j]);//修护 } } } int maxx = -1; for(int i = 1;i <= top;i++){ maxx = max(maxx,dp[N][i]); } printf("%d\n",maxx); } return 0; }