poj-1384 Piggy-Bank

# include <cstdio>
# include <cstring>
# include <iostream>
# include <algorithm>
using namespace std;

int st,en,n;
int f[502][10004],w[10004],v[10004];

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&st,&en);
        int V=en-st;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&w[i]);
        memset(f,0x3f3f3f3f,sizeof(f));
        for(int i=1;i<=n;i++){
            f[i][0]=0;
            for(int j=1;j<=V;j++){
                if(j<w[i]) f[i][j]=f[i-1][j];
                else f[i][j]=min(f[i-1][j],f[i][j-w[i]]+v[i]);
            }
        }
        if(f[n][V]>=0x3f3f3f3f) printf("This is impossible.\n");
        else printf("The minimum amount of money in the piggy-bank is %d.\n",f[n][V]);
    }
    return 0;
}
/**********************************************************
完全背包问题,物品一定可以装满背包。
有 n 件物品,每件物品有 w[i] 的花费,v[i] 的价值,每件物品可以选择
无数件,求容量为 V 的背包的最大(最小)价值,
我觉得完全背包是背包里面最简单的一种背包,f[i][j]表示前 i 个物品价值
为 j 时的最大(最小)价值,对于当前的第 i 个物品可以选择0~x|x*w[i]<=j
件,可以用三重循环来做

for i:1~n
    for j:1~V
        for k 0~x|x*w[i]<=j
        f[i][j]=max{f[i-1][j-k*w[i]]+v[i]}
        
优化过之后就是去掉了k的那一层循环,意思就是,f[i][j-k*w[i]]+k*v[i]
这个状态可以由f[i][j-(k-1)*w[i]]+(k-1)*v[i]转移过来,而最终的又可以
由f[i-1][j]转移过来,也就是说,对于第 i 件物品选择 k 件时的最大(最
小)价值可以由选择 k-1 件第 i 件物品时的价值 +v[i]得到。

至于空间复杂度,%>_<% 先这样吧,
那,就着这样吧。

*********************************************************************
3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4

**********************************************************************

 

posted @ 2017-04-28 23:27  林探惜  阅读(143)  评论(0编辑  收藏  举报