令dp[i][j][0]表示前i种物品花费最多j钱不买第i种物品可以获得的最大糖果数,dp[i][j][1]表示前i种物品花费最多j钱买第i种物品可以获得的最大糖果数,然后转移即可。第一维可以压缩掉。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 2001; 7 int dp[N][2]; 8 9 int main () 10 { 11 int t; 12 scanf("%d", &t); 13 while ( t-- ) 14 { 15 int m, n; 16 scanf("%d%d", &m, &n); 17 memset( dp, 0, sizeof(dp) ); 18 for ( int i = 1; i <= n; i++ ) 19 { 20 int w, a, b; 21 scanf("%d%d%d", &w, &a, &b); 22 for ( int j = 0; j <= m; j++ ) 23 { 24 dp[j][0] = max( dp[j][0], dp[j][1] ); 25 } 26 for ( int j = w; j <= m; j++ ) 27 { 28 dp[j][1] = max( dp[j - w][1] + a, dp[j - w][0] + a + b ); 29 } 30 } 31 printf("%d ", max( dp[m][0], dp[m][1] )); 32 } 33 return 0; 34 }