{dp入门}
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了{dp入门}相关的知识,希望对你有一定的参考价值。
之前一直比较恐惧dp的题,暑假之前好好从头补一下。
题目链接:HihoCoder - 1037
数字三角形
dp[i][j]表示到第i层第j个房间时累计收集到的最大值,从上到下记忆化搜索即可
状态转移:dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+m[i][j];
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 int n; 6 int m[110][110]; 7 int dp[110][110]; 8 int main() 9 { 10 while(scanf("%d",&n)!=EOF) 11 { 12 memset(m,0,sizeof(m)); 13 memset(dp,0,sizeof(dp)); 14 int ans=0; 15 for(int i=1;i<=n;i++) 16 for(int j=1;j<=i;j++) 17 scanf("%d",&m[i][j]); 18 for(int i=1;i<=n;i++) 19 for(int j=1;j<=i;j++) 20 dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+m[i][j]; 21 for(int i=1;i<=n;i++) 22 ans=max(ans,dp[n][i]); 23 printf("%d\n",ans); 24 } 25 }
题目链接:HihoCoder - 1038
01背包
dp[j]=max(dp[j-c[i]]+v[i],dp[j]);
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int maxn=520; 6 int n,m; 7 int dp[100110]; 8 int c[maxn],v[maxn]; 9 int main() 10 { 11 scanf("%d%d",&n,&m); 12 for(int i=0;i<n;i++) 13 scanf("%d%d",&c[i],&v[i]); 14 for(int i=0;i<n;i++) 15 for(int j=m;j>=c[i];j--) 16 dp[j]=max(dp[j-c[i]]+v[i],dp[j]); 17 printf("%d\n",dp[m]); 18 }
题目链接:HihoCoder - 1043
完全背包
和01背包相比只是j的顺序变了
本质是为了01背包只能选一件,完全背包可以多选
即01背包时的dp[ j-c[i] ]是上一次遍历时求出的,而完全背包用的则是本次遍历求出的值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int maxn=520; 6 int n,m; 7 int dp[100110]; 8 int c[maxn],v[maxn]; 9 int main() 10 { 11 scanf("%d%d",&n,&m); 12 for(int i=0;i<n;i++) 13 scanf("%d%d",&c[i],&v[i]); 14 for(int i=0;i<n;i++) 15 for(int j=c[i];j<=m;j++) 16 dp[j]=max(dp[j-c[i]]+v[i],dp[j]); 17 printf("%d\n",dp[m]); 18 }
以上是关于{dp入门}的主要内容,如果未能解决你的问题,请参考以下文章