hdu 1565 方格取數(狀壓dp)
阿新 • • 發佈:2018-12-12
給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。
Input
包括多個測試例項,每個測試例項包括一個整數n 和n*n個非負數(n<=20)
Output
對於每個測試例項,輸出可能取得的最大的和
Sample Input
3
75 15 21
75 15 28
34 70 5
Sample Output
188
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 20000 int dp[25][maxn], sta[maxn]; int a[25][25]; int n,cnt; using namespace std; void init() {cnt=0; for(int i=0;i<(1<<n);i++) { if(i&(i<<1)) continue; sta[cnt++]=i; } } int main() { while(~scanf("%d",&n)) {memset(dp,0,sizeof(dp)); memset(sta,0,sizeof(sta)); init(); int ans=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&a[i][j]); for(int i=0;i<cnt;i++) for(int j=0;j<n;j++) { if((sta[i]&(1<<j))>0) dp[0][i]+=a[0][j]; if(dp[0][i]>ans) ans=dp[0][i]; } for(int i=1;i<n;i++) for(int j=0;j<cnt;j++) { for(int k=0;k<cnt;k++) if((sta[j]&sta[k])==0) dp[i][j]=max(dp[i][j],dp[i-1][k]); for(int k=0;k<n;k++) if((sta[j]&(1<<k))>0) dp[i][j]+=a[i][k]; if(ans<dp[i][j]) ans=dp[i][j]; } printf("%d\n",ans); } return 0; }