hdu 1565 方格取数(1) (状态压缩dp)
2014-08-04 12:58
597 查看
题目链接:点击打开链接
本题的测试实例其实是n<=16不然用状压是过不了的 17000*17000*20 必须TLE的
本题的测试实例其实是n<=16不然用状压是过不了的 17000*17000*20 必须TLE的
#include<stdio.h> #include<string.h> int dp[25][20000];//存第i层 取第j种状态能得到的最大值 int num[20000];//存合法状态 int map[25][25];//存矩阵 int limit;//枚举上界 void init(int n)//初始化 { memset(dp,0,sizeof(dp)); int i,j,sum; for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&map[i][j]); } } for(i=0;num[i]<limit;i++)//先初始化第0行dp[0][k]的值 { sum=0; for(j=0;(1<<j)<=num[i];j++) { if(((1<<j)&num[i])!=0) sum+=map[0][j]; } dp[0][i]=sum; // printf("dp[0][%d] %d\n",num[i],dp[0][i]); } //printf("limit %d",limit); } int main() { int i,j,k,n,size,sum,max; size=0; limit=1<<20; for(i=0;i<limit;i++)//枚举所有合法状态 每一行内没有相邻的两个1 共17000多种 { if((i&(i<<1))==0) num[size++]=i; } while(scanf("%d",&n)!=EOF) { if(n==0) { printf("0\n"); continue; } limit=1<<n; //printf("limit %d\n",limit); init(n); for(i=1;i<n;i++)//第0行已经初始化过 从第一行dp { for(j=0;num[j]<limit;j++)//遍历当前行的合法状态 { sum=0;//存当前行所取的数字之和 max=0;// 上一层与当前行不冲突的状态的最大值 for(k=0;(1<<k)<=num[j];k++)//求当前行所取的数字之和 { if(((1<<k)&num[j])!=0) sum+=map[i][k]; } // printf("sum %d\n",sum); for(k=0;num[k]<=limit;k++)//求上一层与当前行不冲突的状态的最大值 { if((num[k]&num[j])==0) { if(dp[i-1][k]>max)max=dp[i-1][k]; } } dp[i][j]=max+sum; // printf(" i j %d %d %d\n",i,num[j],dp[i][j]); } } max=0; for(i=0;i<limit;i++) { if(dp[n-1][i]>max)max=dp[n-1][i]; } printf("%d\n",max);// dp到最后一层的最大值就是最终的结果了 } return 0; }
相关文章推荐
- hdu 1565 方格取数(1)(状态压缩DP)
- hdu 1565 方格取数(1) 状态压缩dp
- HDU 1565 方格取数(1)(状态压缩DP)
- hdu 1565 方格取数(1)(状态压缩dp)
- HDU 1565 方格取数(1) (状态压缩DP入门题 2)(待更新)
- hdu 1565 方格取数(1)(DP 状态压缩)
- Hdu-1565 方格取数(1) (状态压缩dp入门题
- 状态压缩DP——hdu 1565 方格取数1
- hdu 1565 方格取数(1) (状态压缩DP)
- HDU1565方格取数(1)(状态压缩DP)
- HDU 1565 方格取数(1) (状态压缩 DP)
- hdu 1565 方格取数(1) 状态压缩dp
- hdu 1565 方格取数(1)(DP 状态压缩)
- HDU1565 方格取数(1) (状态压缩DP)
- HDU 1565 方格取数(1) 状态压缩DP
- hdu 1565 方格取数(1) (状态压缩DP)
- hdu 1565 方格取数(1)(状态压缩dp)
- HDU 1565 方格取数(1)(插头DP||状态压缩)
- HDU1565 方格取数(1)(状态压缩dp)
- HDU 1565 方格取数(1)(状态压缩DP)