ACM板子——【动态规划问题】全收录
一、背包问题
【1.1】01背包
1 for(int i=1;i<=n;i++) 2 for(int j=m;j>=v[i];j--) 3 f[j]=max(f[j],f[j-v[i]]+w[i]);
【1.2】完全背包
1 for(int i=1;i<=n;i++) 2 for(int j=v[i];j<=m;j++) 3 f[j]=max(f[j],f[j-v[i]]+w[i]);
【1.3】多重背包问题1
1 for(int i=0;i) 2 { 3 int v,w,s; 4 cin>>v>>w>>s; 5 for(int j=m;j>=0;j--) 6 for(int k=1;k<=s&&k*v<=j;k++) 7 f[j]=max(f[j],f[j-k*v]+k*w); 8 }
【1.4】多重背包问题2(数据更大的情况下,二进制优化)
1 #include2 #include 3 #define endl '\n' 4 #define ll long long 5 using namespace std; 6 const int N=3e4+10; 7 int f[N],v[N],w[N]; 8 int main() 9 { 10 int n,m; 11 cin>>n>>m; 12 int cnt=0; 13 for(int i=1;i<=n;i++) 14 { 15 int a,b,s; 16 cin>>a>>b>>s; 17 int k=1; 18 while(k<=s) 19 { 20 cnt++; 21 v[cnt]=a*k; 22 w[cnt]=b*k; 23 s-=k; 24 k*=2; 25 } 26 if(s>0) 27 { 28 cnt++; 29 v[cnt]=a*s; 30 w[cnt]=b*s; 31 } 32 } 33 n=cnt; 34 for(int i=1;i<=n;i++) 35 for(int j=m;j>=v[i];j--) 36 f[j]=max(f[j],f[j-v[i]]+w[i]); 37 cout< endl; 38 return 0; 39 }
【1.5】多重背包问题3(单调队列优化)
【1.6】混合背包问题
【1.7】二维费用背包问题
1 #include2 using namespace std; 3 const int N=110; 4 int f[N][N]; 5 int main() 6 { 7 int n,v,m; 8 cin>>n>>v>>m; 9 for(int i=0;i ) 10 { 11 int a,b,c; 12 cin>>a>>b>>c; 13 for(int j=v;j>=a;j--) 14 for(int k=m;k>=b;k--) 15 f[j][k]=max(f[j][k],f[j-a][k-b]+c); 16 } 17 cout<<f[v][m]; 18 return 0; 19 }
【1.8】分组背包问题
1 #include2 using namespace std; 3 const int N=110; 4 int f[N],v[N],w[N]; 5 int main() 6 { 7 int n,m; 8 cin>>n>>m; 9 for(int i=1;i<=n;i++) 10 { 11 int s; 12 cin>>s; 13 for(int j=1;j<=s;j++) cin>>v[j]>>w[j]; 14 for(int j=m;j>=0;j--) 15 for(int k=1;k<=s;k++) 16 if(j>=v[k]) 17 f[j]=max(f[j],f[j-v[k]]+w[k]); 18 } 19 cout<<f[m]; 20 return 0; 21 }
二、线性DP
【2.1】数字金字塔
1 #include2 using namespace std; 3 const int N=510; 4 int f[N][N],w[N][N]; 5 int main() 6 { 7 int n; 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 for(int j=1;j<=i;j++) 11 cin>>w[i][j]; 12 for(int i=n;i;i--) 13 for(int j=1;j<=i;j++) 14 f[i][j]=max(f[i+1][j]+w[i][j],f[i+1][j+1]+w[i][j]); 15 cout< 1][1]; 16 }
【2.3】最长上升子序列
1 #include2 using namespace std; 3 const int N=1e5+10; 4 int a[N],f[N]; 5 int main() 6 { 7 int n; 8 cin>>n; 9 for(int i=1;i<=n;i++) cin>>a[i]; 10 for(int i=1;i<=n;i++) 11 { 12 f[i]=1; 13 for(int j=1;j) 14 if(a[j]<a[i]) 15 f[i]=max(f[i],f[j]+1); 16 } 17 int ans=0; 18 for(int i=1;i<=n;i++) ans=max(ans,f[i]); 19 cout< endl; 20 return 0; 21 }
【2.4】最长上升子序列2