非常妙的一道背包题。
考虑到所有重量都可以凑成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 ",ans); }