cf1132 E. Knapsack

非常妙的一道背包题。

考虑到所有重量都可以凑成840,所以把结果里面每种重量的物品能凑成840的都凑成840.

一旦枚举重量为i的东西超过840的时候,就又相当于从1开始枚举。

所以每种物品的重量至多840,dp[i][j]表示到第i个重量时总重为j时能取到的840最大个数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll cnt[9];
ll dp[10][10000];
int main()
{
    ll w;
    scanf("%lld",&w);
    for(int i=1;i<=8;i++)
       scanf("%lld",&cnt[i]);
    memset(dp,-1,sizeof(dp));
    dp[0][0]=0;
    for(int i=0;i<=7;i++)
    {
        for(int j=0;j<=840*8;j++)
        {
            if(dp[i][j]!=-1)
            {
                ll index=840/(i+1);
                index=min(index,cnt[i+1]);
                for(int k=0;k<=index;k++)
                {
                    dp[i+1][j+k*(i+1)]=max(dp[i+1][j+k*(i+1)],dp[i][j]+(cnt[i+1]-k)/(840/(i+1)));
                }
            }
        }
    }
    ll ans=0;
    for(int i=0;i<=840*8;i++)
    {
        if(i>w||dp[8][i]==-1)
          continue;
        ans=max(ans,i+840*min(dp[8][i],(w-i)/840));
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/lishengkangshidatiancai/p/10547079.html