dp0分求助

P1048 [NOIP2005 普及组] 采药

AC代码,求关 ```cpp #include<bits/stdc++.h> using namespace std; int n,v1,i,j,n1[1010],v[1010]; int dp[1010][1010]={}; int main() { cin>>n>>v1; for(i=1;i<=v1;i++) { cin>>n1[i]>>v[i]; } dp[1][1]=0; for(i=1;i<=v1;i++)//v1与n换位置 { for(j=1;j<=n;j++)//v1是数量,n是空间 { dp[i][j]=dp[i-1][j]; if(j>=n1[i]) dp[i][j]=max(v[i]+dp[i-1][j-n1[i]],dp[i][j]);//dp要判断 //cout<<dp[i][j]<<' '; } //cout<<endl; } cout<<dp[v1][n]; } ```
by k333k @ 2024-07-19 16:58:30


你的代码那个m要逆着枚举,否则会变成完全背包,我之前也挂这了,应为: ```cpp for(int j=vl;j>=1;j--) ``` 可以自己多了解一下 我的AC代码: ```cpp #include<iostream> #include<algorithm> using namespace std; int dp[110][1010],w[1010],v[1010]; int main(){ int m,t,ans=0,a; cin>>t>>m; for(int i=1;i<=m;i++){ cin>>w[i]>>v[i]; } for(int i=1;i<=t;i++){ int b=i; for(int j=1;j<=m;j++){ if(b>=w[j]){ dp[j][i]=max(dp[j-1][i-w[j]]+v[j],dp[j-1][i]); if(dp[j][i]==dp[j-1][i-w[j]])b-=w[j]; a=dp[j][i]; if(a>ans)ans=a; } else{ dp[j][i]=dp[j-1][i]; a=dp[j][i]; if(a>ans)ans=a; } } } cout<<ans; return 0; } ```
by pwchrvj @ 2024-07-22 17:04:23


## **upd**: ```cpp #include<bits/stdc++.h> using namespace std; int n,v1,i,j,ans,n1[1010],v[1010]; int dp[1010]; int main() { cin>>n>>v1; for(i=1;i<=v1;i++) { cin>>n1[i]>>v[i]; } memset(dp,0xff,sizeof(dp)); dp[0]=0; for(i=1;i<=v1;i++) { for(j=n;j>=n1[i];j--) { dp[j]=max(v[i]+dp[j-n1[i]],dp[j]); } } for(i=0;i<=n;i++) ans=max(ans,dp[i]); cout<<ans; } ``` 代码改完了: 1.dp[ ] 可以优化掉一维; 2.v1 和 n 写反了; 3.dp数组要初始化为无穷小; 4.最后最好扫一遍。
by pwchrvj @ 2024-07-22 17:22:37


AC code: ```cpp #include<bits/stdc++.h> using namespace std; int t,m; int v[10001],w[10001],dp[10001][10001]; int main(){ cin>>t>>m; for(int i=1;i<=m;i++)cin>>w[i]>>v[i]; //memset(dp,127,sizeof(dp)); for(int i=1;i<=m;i++){ for(int j=1;j<=t;j++){ if(j<w[i]) dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); } } cout<<dp[m][t]<<endl; return 0; } ```
by HappyFlorr @ 2024-07-26 22:37:38


|