根据题意,因为最多只有五种属性,所以可以通过其中几种属性是否确定了来进行DP。
有这个想法是因为整体的最大值是由某个物品的其中某些属性来确定的,dp的时候可以独立的求出那些确定了的属性的值,通过不断更新,最后找到整体的最大值。
复杂度是O(k*3^k*n),当k大于5的时候,跟等于5的时候是一样的,所以k=min(k, 5)。
代码如下:
View Code
1 #define REP(i, n) for (int i = 0; i < (n); i++) 2 #define REP_1(i, n) for (int i = 1; i <= (n); i++) 3 4 int dp[N][M], rec[LEN][N - 1]; 5 6 int work(int n, int m) { 7 m = min(m, 5); 8 REP_1(i, m) { 9 REP(j, M) { 10 for (int t = j; t; t = (t - 1) & j) { 11 int op = j - t; 12 REP(k, n) { 13 int sum = 0; 14 REP(p, 5) { 15 if (t & (1 << p)) sum += rec[k][p]; 16 } 17 dp[i][j] = max(dp[i][j], dp[i - 1][op] + sum); 18 } 19 } 20 } 21 } 22 return dp[m][M - 1]; 23 } 24 25 int main() { 26 int n, m, T; 27 scanf("%d", &T); 28 while (T-- && ~scanf("%d%d", &n, &m)) { 29 _clr(rec); 30 _clr(dp); 31 REP(i, n) REP(j, 5) scanf("%d", &rec[i][j]); 32 printf("%d\n", work(n, m)); 33 } 34 return 0; 35 }
——written by Lyon