HDU_1114 PiggyBank ( dp | 完全背包问题 )

文章目录

  • 题意
  • 题解
  • 代码

题目连接 hdu or vj

题意

给 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,
绿圈指的是第一件物品地推过程, 同理紫圈第二件
HDU_1114 PiggyBank ( dp | 完全背包问题 )_第1张图片

代码

#include  
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 ; 
} 

你可能感兴趣的:(#,动态规划)