首页 > 代码库 > Wikioi 1025 01背包变形

Wikioi 1025 01背包变形

这题多加了菜品必选编号,所以刚开始不知道怎么写,原来就把必选的处理下就行了,因为有重复,但是相同的价值与价格都一样,所以这里就直接挑出来就行了。

把不是必选的在里面用dp即可,dp之前也要把重复的舍去。

因为总价格容量为浮点数,所以先乘以10变成整数就可以用01背包了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 204
#define MN 1008
#define INF 2000000000
#define eps 1e-8
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int dp[1005];
int n,k,i,j,v,a,b,p[1005],w[1003],p1[1005],w1[1003];
int vis[1005],kind[1005],sum,cnt;
int main()
{

    double v1;
    scanf("%d%d%lf",&n,&k,&v1);
    v=v1*10;
    for(i=1; i<=n; i++) scanf("%lf",&v1),p[i]=v1*10;
    for(i=1; i<=n; i++) sca(w[i]);
    for(i=1; i<=n; i++) sca(kind[i]);
    for(i=1; i<=k; i++)
    {
        sca(a);
        for(j=1; j<=n; j++)
            if(kind[j]==a) kind[j]=0,b=j;
        v-=p[b],sum+=w[b];
    }
    for(i=1; i<=n; i++)
        if(kind[i]&&!vis[kind[i]])
            vis[kind[i]]=1,p1[++cnt]=p[i],w1[cnt]=w[i];
    for(i=1; i<=cnt; i++)
        for(j=v; j>=p1[i]; j--)
            dp[j]=max(dp[j],dp[j-p1[i]]+w1[i]);
    cout<<dp[v]+sum<<endl;
    return 0;
}