01背包大家一定都会……
但如果01背包的W很大怎么办……
此时我们观察,若v[i]很小,我们可以考虑建立有关v[i]的方程
方程内容大概是:在达到某一v时,所需的总w最小
说多了不如上代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 using namespace std; 8 int n,m,sumv,ans; 9 int dp[300][234000],w[500],v[500],wi,vi; 10 int a[300]; 11 int main(){ 12 scanf("%d %d",&n,&m); 13 for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&v[i]); 14 for(int i=1;i<=n;i++) sumv+=v[i]; 15 for(int j=0;j<=sumv;j++) dp[0][j]=200000000; 16 for(int i=1;i<=n;i++) 17 for(int j=sumv;j>=1;j--){ 18 wi=w[i]; 19 vi=v[i]; 20 if(j<=v[i]) dp[i][j]=min(dp[i-1][j],w[i]); 21 else{ 22 dp[i][j]=dp[i-1][j]; 23 dp[i][j]=min(dp[i][j],dp[i-1][j-v[i]]+w[i]); 24 } 25 } 26 for(int i=1;i<=sumv;i++) if(dp[n][i]<=m) ans=i; 27 printf("%d\n",ans); 28 return 0; 29 }
时间: 2024-12-23 14:00:06