跟背包问题非常像,很巧妙,跟着提示做即可
需要注意的是,状态压缩以后,j的变化不是规律的,所以用一个临时缓冲back保存下一次迭代的结果。
代码:
1 #include <iostream> 2 3 using namespace std; 4 5 int onesum(int a) { 6 int sum = 0; 7 while (a) { 8 a &= (a - 1); 9 sum++; 10 } 11 return sum; 12 } 13 14 int main() { 15 int N, M, Q; 16 int w[1024] = {0}; 17 int res[1024] = {0}; 18 int back[1024] = {0}; 19 int mask = 0; 20 21 cin >> N >> M >> Q; 22 for (int i = 0; i < N; i++) 23 cin >> w[i]; 24 25 mask = (1 << (M - 1)) - 1; 26 for (int i = N - 1; i >= 0; i--) { 27 for (int j = 0; j <= mask; j++) { 28 if (onesum(j) < Q) 29 back[j] = max(res[((j << 1) + 1) & mask] + w[i], res[(j << 1) & mask]); 30 else 31 back[j] = res[(j << 1) & mask]; 32 } 33 for (int j = 0; j <= mask; j++) 34 res[j] = back[j]; 35 } 36 37 cout << res[0] << endl; 38 return 0; 39 }