[DP-完全背包] HDU 1114

来源:互联网 发布:复古照片相关软件 编辑:程序博客网 时间:2024/06/06 19:24

题意

给出存钱罐本身的重量和装钱后的重量,以及存钱罐中钱的面值和重量,求存钱罐装满时,钱的总和最小是多少

思路

完全背包解题,每种钱币都可以装无限个,注意初始化的值
每种硬币的数量都不限制,因此是个完全背包。初始化dp数组时需注意,因为求的最小,且题目的意思是恰好装满,所以dp数组初始化为INF,但dp[0] = 0,意为此时只有容量为0 的背包可以在什么也不装且价值为0 的情况下被“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态(背包九讲)
dp[ i ] = min ( dp[ i ], dp[ i - w[ j ] ] + v[ j ] );

代码

#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#define N 10005#define INF 0x7f7f7f7fusing namespace std;int v[ N ], w[ N ]; // value weightint dp[ N ];int knapsack ( int n, int wei ) {    memset ( dp, INF, sizeof ( dp ) );    dp[ 0 ] = 0;    for ( int i = 1; i <= wei; ++i ) {        for ( int j = 0; j < n; ++j ) {            if ( i >= w[ j ] )                dp[ i ] = min ( dp[ i ], dp[ i - w[ j ] ] + v[ j ] );        }    }    return dp[ wei ];}int main () {    int T;    scanf ( "%d", &T );    while ( T-- ) {        int E, F;        scanf ( "%d%d", &E, &F );        int n;        scanf ( "%d", &n );        for ( int i = 0; i < n; ++i )            scanf ( "%d%d", &v[ i ], &w[ i ] );        int sol = knapsack ( n, F - E );        if ( sol != INF )            printf ( "The minimum amount of money in the piggy-bank is %d.\n", sol );        else            printf ( "This is impossible.\n" );    }    return 0;}
原创粉丝点击