总结:
1.尝试设计多个状态转移方程
2.这道题记录分组的思想与分组背包由异曲同工之妙
#include<bits/stdc++.h> using namespace std; int dp[32005], val[65], w[65], sum[65], c[65][20], p[65]; int n, m; int main() { cin >> n >> m; for(int i = 1; i <= m; i++) { cin >> w[i] >> val[i] >> p[i]; if(p[i] != 0) { sum[p[i]]++; c[p[i]][sum[p[i]]] = i; } } for(int i = 1; i <= m; i++) for(int j = n; j >= 0; j--) if(p[i] == 0) { if(j >= w[i]) dp[j] = max(dp[j], dp[j-w[i]]+val[i]*w[i]); if(sum[i] > 0) { if(sum[i] == 1) { if(j >= w[i]+w[c[i][1]]) dp[j] = max(dp[j], dp[j-w[i]-w[c[i][1]]]+val[i]*w[i]+val[c[i][1]]*w[c[i][1]]); } if(sum[i] == 2) { if(j >= w[i]+w[c[i][1]]) dp[j] = max(dp[j], dp[j-w[i]-w[c[i][1]]]+val[i]*w[i]+val[c[i][1]]*w[c[i][1]]); if(j >= w[i]+w[c[i][2]]) dp[j] = max(dp[j], dp[j-w[i]-w[c[i][2]]]+val[i]*w[i]+val[c[i][2]]*w[c[i][2]]); if(j >= w[i]+w[c[i][1]]+w[c[i][2]]) dp[j] = max(dp[j], dp[j-w[i]-w[c[i][1]]-w[c[i][2]]]+val[i]*w[i]+val[c[i][1]]*w[c[i][1]]+val[c[i][2]]*w[c[i][2]]); } } } cout << dp[n]; return 0; }