题意
给 T 组 样例,
每组第一行 空罐的重量, 装满的重量
每组 n 种 物品
价值, 重量
求 最小价值
题解
数量不限, 那么完全背包问题板子直接上, 不过这个是求的最小价值
那么来想一下, 求最大价值的时候, dp[] 数组是全都清零
那么求最大值, 就需要初始化为 INF,
但是这样还漏掉了一点, 接着看, 来模拟一下,
重量为0时, min( dp[i], dp[i-wei[i]]+val[i] );
其中, dp[0] = INF, dp[i-wei[i]]+val[i] = INF+val[i]
重量为0 的价值就变成了 INF
这样会导致整个地推过程都是 INF,
所以, 在初始化一下 dp[0] = 0, 表示背包容量为 0 的时候, 价值为0,
这样, 第一件物品价值就是 0 了, 如此递推到最后一件, 即为所求
可以手动模拟一下 dp[0] = 0 和 dp[0] = INF 两者的区别,
表格黑色为 dp[0] = 0, 红色为 dp[0] = INF,
绿圈指的是第一件物品地推过程, 同理紫圈第二件
代码
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
const int maxn = 5e2+100;
const int maxm = 1e5+100;
int wei[maxn], val[maxn],
dp[maxm];
const int INF = 0x3f3f3f3f;
int main ( ) { // freopen( "F:\\in\\.txt" , "r" , stdin );
int T,
n,
pack_empty, pack_full;
sc( "%d", &T );
while ( T-- ) {
memset( dp, INF, sizeof(dp) );
dp[0] = 0; // 重量为 0 时价值为 0
sc( "%d%d", &pack_empty, &pack_full );
sc( "%d", &n );
for ( int i = 0; i < n; ++i ) {
sc( "%d%d", &val[i], &wei[i]);
}
int m = pack_full-pack_empty;
for( int i = 0; i < n; ++i ){
for( int j = wei[i]; j <= m; ++j ) {
dp[j] = min( dp[j] , dp[j-wei[i]]+val[i] );
}
}
dp[m] != INF ?
pf( "The minimum amount of money in the piggy-bank is %d.\n", dp[m] )
:
puts( "This is impossible." );
}
return 0 ;
}