{dp入門}
阿新 • • 發佈:2017-05-27
code 記憶 題目 memset mem bsp 記憶化 span space
之前一直比較恐懼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[110View Code][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(inti=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 }View Code
題目鏈接: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 }View Code
{dp入門}