HDU 1565 方格取數(1) (狀壓DP)
阿新 • • 發佈:2018-11-08
http://acm.hdu.edu.cn/showproblem.php?pid=1565
#include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; int dp[25][20000], s[20000], len, Map[25][25], n; int check(int m) { if( (m & (m<<1)) != 0)//非法狀態 return 0; return 1; } void Inint() { len = 0;//最大取值只有17771 for(int i = 0; i < (1<<n); i++) { if(check(i)) s[len++] = i; } } int Count(int id, int m) { int d = n-1, sum = 0; while(m > 0) { if(m & 1) sum += Map[id][d]; d--; m = m >>1; } return sum; } int main() { while(scanf("%d", &n) != EOF) { if(n == 0) { printf("0\n"); continue; } memset(dp, 0, sizeof(dp)); memset(Map, 0, sizeof(Map)); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) scanf("%d", &Map[i][j]); Inint(); for(int i = 0; i < len; i++) dp[0][i] = Count(0, s[i]); int ans = 0; for(int r = 1; r < n; r++) { for(int i = 0; i < len; i++) for(int j = 0; j < len; j++) if((s[i] & s[j]) == 0) {//這個可以融合 dp[r][i]= max( dp[r][i], dp[r-1][j]+Count(r,s[i])); } } for(int i = 0; i < len; i++) if(dp[n-1][i]>ans) ans = dp[n-1][i]; printf("%d\n",ans); } return 0; }