这题 还好 我A了之后 习惯性地去看了下 discuss 然后发现 基本上所有人的解法都在说 二维费用完全背包。。。
还好 看到一个人 是和我一样的用 一维 完全背包 加一个计数的cnt数组去解决的。。。
还好 在那边看到了一个人的质疑 并给出了一组数据 果然 一维的不能通过=-=那就只能 去学下 二维费用背包了...擦 这名字好长啊
因为 当时 我背包九讲只学到了01 完全 多重 后面就没学了 。。。
二维费用背包要是一般的话 很简单的 就是多了一层for而已 而且假如这个数组是dp[ i ] [ u[i] ] [ v[i] ]那么u[i] , v[i]的遍历前后顺序对面最终结果是没有影响 只要你自己开的数组与这个前后遍历顺序相对应
我将 错误的代码 也放上来好了。。。 虽然A了。只能怪 测试数据太弱了 同时 附上 测试数据
1 /* 2 92 7 3 3 3 30 2 4 40 3 5 12 1 6 */ 7 #include <iostream> 8 #include <cstring> 9 using namespace std; 10 11 const int size = 110; 12 int dp[size]; 13 int cnt[size]; 14 int weight[size]; 15 int val[size]; 16 17 int main() 18 { 19 int n , m , k , s , ans; 20 while( cin >> n >> m >> k >> s ) 21 { 22 ans = -1; 23 for( int i = 1 ; i<=k ; i++ ) 24 { 25 cin >> val[i] >> weight[i]; 26 } 27 memset( dp , 0 , sizeof(dp) ); 28 memset( cnt , 0 , sizeof(cnt) ); 29 for( int i = 1 ; i<=k ; i++ ) 30 { 31 for( int j = weight[i] ; j<=m ; j++ ) 32 { 33 if( dp[ j-weight[i] ] + val[i] > dp[j] ) 34 { 35 dp[j] = dp[ j-weight[i] ] + val[i]; 36 cnt[j] = cnt[ j-weight[i] ] + 1; 37 } 38 } 39 } 40 for( int i = 1 ; i<=m ; i++ ) 41 { 42 if( dp[i]>=n && cnt[i]<=s ) 43 { 44 ans = m-i; 45 break; 46 } 47 } 48 cout << ans << endl; 49 } 50 return 0; 51 }
1 // 二维 费用 背包 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int size = 110; 8 int val[size]; 9 int weight[size]; 10 int dp[size][size];//一维 忍耐度 二维 杀怪数 11 12 int main() 13 { 14 int n , m , k , s , ans; 15 bool flag; 16 while( cin >> n >> m >> k >> s ) 17 { 18 flag = false; 19 for( int i = 1 ; i<=k ; i++ ) 20 { 21 cin >> val[i] >> weight[i]; 22 } 23 memset( dp , 0 , sizeof(dp) ); 24 for( int i = 1 ; i<=k ; i++ ) 25 { 26 for( int j = weight[i] ; j<=m ; j++ ) 27 { 28 for( int p = 1 ; p<=s ; p++ ) 29 { 30 dp[j][p] = max( dp[j][p] , dp[ j-weight[i] ][ p-1 ] + val[i] ); 31 } 32 } 33 } 34 if( dp[m][s] <n ) 35 cout << -1 << endl; 36 else 37 { 38 for( int i = 1 ; i<=m ; i++ ) 39 { 40 for( int j = 1 ; j<=s ; j++ ) 41 { 42 if( dp[i][j]>=n ) 43 { 44 ans = m-i; 45 flag = true; 46 break; 47 } 48 } 49 if( flag ) 50 break; 51 } 52 cout << ans << endl; 53 } 54 } 55 return 0; 56 }