【题解】lugu P4095 Eden的新背包问题

总结:
1.

 

50分的代码(因为由多个数据,所以不能改变num[]数组)

#include<bits/stdc++.h>
using namespace std;
struct node{
    int pos, value;
}que[1005];
int c[1005], w[1005], num[1005], f[1005], vis[1005];
int n, head, tail, V, q, h, z[1005];
int main()
{
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> c[i] >> w[i] >> num[i];
    cin >> q;
    for(int cnt = 1; cnt <= q; cnt++)
{    
    memset(f, 0, sizeof(f));
    cin >> h >> V;
    vis[h] = 1;
    for(int i=0;i<n;i++) 
{
    if(!vis[i])
    {
    z[i] = min(num[i], V/c[i]);  //用z[]数组代表能用多少件物品
    for(int mo=0;mo<c[i];mo++) 
    {
        head=tail=0;
        for(int k=0;k<=(V-mo)/c[i];k++) 
        {
            int x=k;
            int y=f[k*c[i]+mo]-k*w[i];
            while(head<tail && que[head].pos<k-z[i])head++;
            while(head<tail && que[tail-1].value<=y)tail--;
            que[tail].value=y,que[tail].pos=x;
            tail++;
            f[k*c[i]+mo]=que[head].value+k*w[i];
        }
    }
    }    
}
cout << f[V] << endl;
vis[h] = 0;
}
return 0;
}

 

正解

#include<bits/stdc++.h>
using namespace std;
long long n, q, d, e, ans, vis[1010]; 
long long dp[1010][1010], f[1010][1010], val[1010], w[1010], c[1010];
long long re,p;
void pre()
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= 1000; j++)
        dp[i][j] = dp[i-1][j];
        re = c[i]; p = 1;
        while(re>=p){
            for(int j=1000;j>=w[i]*p;j--)
                dp[i][j]=max(dp[i][j],dp[i][j-w[i]*p]+val[i]*p);
                re-=p;p=p<<1;
        }
        if(re){
            for(int j=1000;j>=w[i]*re;j--)
                dp[i][j]=max(dp[i][j],dp[i][j-w[i]*re]+val[i]*re);
        }
    }

    for(int i = n; i >= 1; i--)
    {
        for(int j = 1; j <= 1000; j++)
            f[i][j] = f[i+1][j];
        re = c[i]; p = 1;
        while(re>=p){
            for(int j=1000;j>=w[i]*p;j--)
                f[i][j]=max(f[i][j], f[i][j-w[i]*p]+val[i]*p);
                re-=p;p=p<<1;
        }
        if(re){
            for(int j=1000;j>=w[i]*re;j--)
                f[i][j]=max(f[i][j],f[i][j-w[i]*re]+val[i]*re);
        }

    }
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> w[i] >> val[i] >> c[i];
    pre();
    cin >> q;
    while(q--)
    {
        ans = 0;
        cin >> d >> e;
        d++;
        for(int i = 0; i <= e; i++)
            ans = max(ans, dp[d-1][i]+f[d+1][e-i]);
        cout << ans << endl;
    }    
    return 0;
} 

 

posted @ 2019-08-19 00:04  ATKevin  阅读(141)  评论(0编辑  收藏  举报