題意:輸入n 輸入n行n列 從n行中找出n個數 保證任意兩個都不在同一列 求這些數的和。ios
思路:dp[i][j]表示前i個選的列狀態爲j。須要注意的是一個優化,代碼中有標識優化
#include <iostream> #include <cstdio> #include <stack> #include <cstring> using namespace std; int a[20][20]; int dp[20][70000]; int main() { int t, n; scanf("%d", &t); int tt = 1; while(t--) { scanf("%d", &n); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d", &a[i][j]); } } int maxn = 1<<n; for(int i=0; i<=n; i++) for(int j=0; j<=maxn; j++) dp[i][j] = 0; for(int i=1; i<=n; i++) { for(int j=0; j<maxn; j++) { int cnt = 0; for(int k=0; k<n; k++)//一步優化 就是當前i-1的狀態下有不是i-1個組成的話 pass掉 if(j & (1<<k)) cnt++; if (cnt != i-1) continue; for(int k=1; k<=n; k++) { int st = 1<<(k-1); if((st&j)==0) { dp[i][st|j] = max(dp[i][st|j], dp[i-1][j]+a[i][k]); } } } } printf("Case %d: %d\n", tt++, dp[n][(1<<n)-1]); } return 0; }