HDU2167 Pebbles(状压DP)
2016-02-13 22:57
288 查看
题目给一张n×n的格子,每个格子都有数字,要从格子中取若干个数字,八个方向相邻的数字不能一起取,问取的数字最大和是多少。
从第一行一行一行看下去,可以发现第1行取哪几列只会影响到第2行,第3行后面的一点影响都没有。即第i行的决策只受i-1行决策的影响。
那么自然想到状态DP——
dp[i][S]前i行其中第i行取的列的集合是S的取数最大和
dp[i][S]=max(dp[i-1][S'])+集合S数字和(S是S'的合法的下一行的取法)
虽然题目n最多15,集合S就215种状态,但事实上合法的(不能同时取同一行相邻的两列数字)集合S状态只有1000多个。枚举即可转移,为了保证时间复杂度做一些预处理就行了。
从第一行一行一行看下去,可以发现第1行取哪几列只会影响到第2行,第3行后面的一点影响都没有。即第i行的决策只受i-1行决策的影响。
那么自然想到状态DP——
dp[i][S]前i行其中第i行取的列的集合是S的取数最大和
dp[i][S]=max(dp[i-1][S'])+集合S数字和(S是S'的合法的下一行的取法)
虽然题目n最多15,集合S就215种状态,但事实上合法的(不能同时取同一行相邻的两列数字)集合S状态只有1000多个。枚举即可转移,为了保证时间复杂度做一些预处理就行了。
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; int read(char *&s){ int res=-1; sscanf(s,"%d",&res); while(*s==' ') ++s; while(*s>='0' && *s<='9') ++s; while(*s==' ') ++s; return res; } int n,a[15][15],d[15][1<<15],sta[1<<15],sn; bool isok(int s){ for(int i=1; i<n; ++i){ if(((s>>i-1)&1) && ((s>>i)&1)) return 0; } return 1; } bool isok(int x,int y){ for(int i=0; i<n; ++i){ if(((x>>i)&1)==0) continue; if((y>>i)&1) return 0; if(i>0 && ((y>>i-1)&1)) return 0; if(i<n-1 && ((y>>i+1)&1)) return 0; } return 1; } int main(){ char str[1111]; while(gets(str) && *str){ n=0; char *s=str; int t; while(t=read(s),t!=-1) a[0][n++]=t; for(int i=1; i<n; ++i){ gets(str); s=str; for(int j=0; j<n; ++j) a[i][j]=read(s); } sn=0; for(int i=0; i<(1<<n); ++i){ if(isok(i)) sta[sn++]=i; } memset(d,0,sizeof(d)); for(int i=0; i<sn; ++i){ for(int j=0; j<n; ++j){ if((sta[i]>>j)&1) d[0][sta[i]]+=a[0][j]; } } vector<int> vec[2222]; for(int i=0; i<sn; ++i){ for(int j=0; j<sn; ++j){ if(isok(sta[i],sta[j])) vec[i].push_back(j); } } for(int i=1; i<n; ++i){ for(int j=0; j<sn; ++j){ for(int k=0; k!=vec[j].size(); ++k) d[i][sta[j]]=max(d[i][sta[j]],d[i-1][sta[vec[j][k]]]); for(int k=0; k<n; ++k){ if((sta[j]>>k)&1) d[i][sta[j]]+=a[i][k]; } } } int res=0; for(int i=0; i<sn; ++i){ res=max(res,d[n-1][sta[i]]); } printf("%d\n",res); getchar(); } return 0; }
相关文章推荐
- 学stm32感想
- 全面理解面向对象的 JavaScript
- Atitit.mysql 5.0 5.5 5.6 5.7 新特性 新功能
- Atitit.mysql 5.0 5.5 5.6 5.7 新特性 新功能
- Atitit.mysql 5.0 5.5 5.6 5.7 新特性 新功能
- Atitit.业务系统的新特性 开发平台 新特性的来源总结
- BestCoder Round #72 (div.2) A.Clarke and chemistry
- Atitit.业务系统的新特性 开发平台 新特性的来源总结
- JavaWeb项目中的绝对路径与相对路径问题
- Atitit.业务系统的新特性 开发平台 新特性的来源总结
- Leetcode 004 Median of Two Sorted Arrays
- atitit.跨语言执行cmd cli api的原理及兼容性设计草案
- 操作系统学习1
- HDU 4352 XHXJ's LIS(数位dp&状态压缩)
- atitit.跨语言执行cmd cli api的原理及兼容性设计草案
- atitit.跨语言执行cmd cli api的原理及兼容性设计草案
- canvas画简单电路图
- SAE中的日志功能
- Window 7 小常识集合
- Light OJ 1191 Bar Codes (DP)