Training:背包专题

这次背包专题的题目大都是一些模板题,前四题套用模板就可以通过,最后一题题是二维费用背包,但也很基础。
HDU 2602:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=17434
01背包。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1010;
int n,v,w[maxn],c[maxn];
int d[maxn];
void zeroone_pack(int *a, int c, int w)
{
    for(int i = v; i >= c; i--)
        a[i] = max(a[i], a[i - c] + w);
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        memset(d,0,sizeof(d));
        scanf("%d%d",&n,&v);
        for(int i=1;i<=n;++i) scanf("%d",&w[i]);
        for(int i=1;i<=n;++i) scanf("%d",&c[i]);
        for(int i=1;i<=n;++i) zeroone_pack(d,c[i],w[i]);
        printf("%d\n",d[v]);
    }
    return 0;
}

HDU 1114:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=17679
完全背包。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10010;
const int inf=0x3f3f3f3f;
int n,v,p[maxn],c[maxn];
int d[maxn];
void complete_pack(int *a, int c, int w)
{
    for(int i = c; i <= v; i++)
        a[i] = min(a[i], a[i - c] + w);
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        int w1,w2;scanf("%d%d",&w1,&w2);
        v=w2-w1;
        memset(d,0x3f,sizeof(d));
        d[0]=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%d%d",&p[i],&c[i]);
        for(int i=1;i<=n;++i) complete_pack(d,c[i],p[i]);
        if(d[v]==inf) printf("This is impossible.\n");
        else printf("The minimum amount of money in the piggy-bank is %d.\n",d[v]);
    }
    return 0;
}

HDU 2191:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=20468
多重背包。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1010;
int n,v,w[maxn],c[maxn],m[maxn];
int d[maxn];
void complete_pack(int *a, int c, int w)
{
    for(int i = c; i <= v; i++)
        a[i] = max(a[i], a[i - c] + w);
}
void zeroone_pack(int *a, int c, int w)
{
    for(int i = v; i >= c; i--)
        a[i] = max(a[i], a[i - c] + w);
}
void mutiple_pack(int *a, int c, int w, int m)
{
    if(c * m >= v){
        complete_pack(a, c, w);
        return;
    }
    int k = 1;
    while(k < m)
    {
        zeroone_pack(a, k * c, k * w);
        m = m - k;
        k = 2 * k;
    }
    zeroone_pack(a, c * m, w * m);
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        memset(d,0,sizeof(d));
        scanf("%d%d",&v,&n);
        for(int i=1;i<=n;++i) scanf("%d%d%d",&c[i],&w[i],&m[i]);
        for(int i=1;i<=n;++i) mutiple_pack(d,c[i],w[i],m[i]);
        printf("%d\n",d[v]);
    }
    return 0;
}

HDU 4508:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=37528
完全背包。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
int n,v,w[maxn],c[maxn];
int d[maxn];
void complete_pack(int *a, int c, int w)
{
    for(int i = c; i <= v; i++)
        a[i] = max(a[i], a[i - c] + w);
}
int main(){
    while(~scanf("%d",&n)){
        memset(d,0,sizeof(d));
        for(int i=1;i<=n;++i) scanf("%d%d",&w[i],&c[i]);
        scanf("%d",&v);
        for(int i=1;i<=n;++i) complete_pack(d,c[i],w[i]);
        printf("%d\n",d[v]);
    }
    return 0;
}

HDU 2159:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=20469
二维费用背包,费用分别为杀的怪的数量和疲劳值,状态转移方程为 d[j][l]=max(d[j][l],d[j1][lc[i]]+v[i])

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110;
int n,m,k,s,v[maxn],c[maxn];
int d[maxn][maxn];
int main(){
    while(~scanf("%d%d%d%d",&n,&m,&k,&s)){
        memset(d,0,sizeof(d));
        for(int i=1;i<=k;++i) scanf("%d%d",&v[i],&c[i]);
        for(int i=1;i<=k;++i)
            for(int j=1;j<=s;++j)
                for(int l=c[i];l<=m;l++)
                    d[j][l]=max(d[j][l],d[j-1][l-c[i]]+v[i]);
        int pos=0;
        while(pos<=m&&d[s][pos]<n) ++pos;
        printf("%d\n",d[s][pos]<n?-1:m-pos);
    }
    return 0;
}

你可能感兴趣的:(ACM,HDU,背包问题)