本周主要练习DP中的背包问题。
1.P1616 疯狂的采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:
完全背包问题。
代码:
#include<cstdio> #include<iostream> using namespace std; long long int t[10010],v[10010]; long long int res[10000010]; int main() { long long int T,M; scanf("%lld%lld",&T,&M); for(int i=1;i<=M;++i) scanf("%lld%lld",&t[i],&v[i]); for(int i=1;i<=M;++i) { for(int j=t[i];j<=T;++j) { res[j]=max(res[j],res[j-t[i]]+v[i]); } } printf("%lld",res[T]); return 0; }
2.P1833 樱花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:
多重背包。将各种不同赏花都视为新情况,转化为01背包。
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,T; int w[100010],c[100010]; int f[100010]; int main() { int h1,h2,m1,m2; scanf("%d:%d%d:%d%d",&h1,&m1,&h2,&m2,&n); T=(h2-h1-1)*60+m2+60-m1; int n1=0; for(int i=1;i<=n;++i) { int x,y,s,k=1; scanf("%d%d%d",&x,&y,&s); if(s==0) s=T/x; while(s>=k) { w[++n1]=x*k;c[n1]=y*k; s-=k;k*=2; } w[++n1]=s*x;c[n1]=s*y; } for(int i=1;i<=n1;++i) { for(int j=T;j>=w[i];--j) f[j]=max(f[j],f[j-w[i]]+c[i]); } printf("%d",f[T]); return 0; }
3.P1077 [NOIP2012 普及组] 摆花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:
同样转化为01背包。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int mod=1000007; int n,m,a[110],f[110]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } f[0]=1; for(int i=1;i<=n;++i) { for(int j=m;j>=0;--j) { int k=min(a[i],j); for(int p=1;p<=k;++p) f[j]=(f[j]+f[j-p])%mod; } } printf("%d",f[m]); return 0; }
4.P1064 [NOIP2006 提高组] 金明的预算方案 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:
将不同附件情况分开讨论。
代码:
#include<iostream> #include<cstdio> using namespace std; int m,n,mw[32010],mv[32010],fw[32010][3],fv[32010][3],f[32010],v,p,q; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&v,&p,&q); if(q==0) { mw[i]=v; mv[i]=v*p; } else { fw[q][0]++; fw[q][fw[q][0]]=v; fv[q][fw[q][0]]=v*p; } } for(int i=1;i<=m;++i) for(int j=n;j>=mw[i];--j) { f[j]=max(f[j],f[j-mw[i]]+mv[i]);//挑选附件几种情况 if(j>=mw[i]+fw[i][1])f[j]=max(f[j],f[j-mw[i]-fw[i][1]]+mv[i]+fv[i][1]); if(j>=mw[i]+fw[i][2])f[j]=max(f[j],f[j-mw[i]-fw[i][2]]+mv[i]+fv[i][2]); if(j>=mw[i]+fw[i][1]+fw[i][2]) f[j]=max(f[j],f[j-mw[i]-fw[i][1]-fw[i][2]]+mv[i]+fv[i][1]+fv[i][2]); } printf("%d",f[n]); return 0; }