首页 > 技术文章 > dp入门题解

zhmlzhml 2020-04-05 17:25 原文

学dp学到自闭(真的判断不出是个dp问题哇)

来看一下最近学的dp简单的题库.

1.01背包问题(P1048)

这个的特点是每种东西只能拿一次.

https://www.luogu.com.cn/problem/P1048

二维dp:

 1  for(int i=1;i<=m;i++)
 2     {
 3         scanf("%d%d",&w[i],&val[i]);
 4     }
 5     for(int i=1;i<=m;i++) 
 6         for(int j=t;j>=0;j--) //注意这个地方是倒着来的 
 7         {
 8             if(j>=w[i])
 9             {
10                 dp[i][j]=max(dp[i-1][j-w[i]]+val[i],dp[i-1][j]);
11             }  
12             else
13             {
14                 dp[i][j]=dp[i-1][j];
15             }              
16         }
17     printf("%d",dp[m][t]);

一维dp:

 1     for(int i=1;i<=m;i++)
 2     {
 3         scanf("%d%d",&w[i],&val[i]);
 4     }
 5     for(int i=1;i<=m;i++) 
 6     {
 7         for(int j=t;j>=0;j--) 
 8         {
 9             if(j>=w[i])
10             {
11                 dp[j]=max(dp[j-w[i]]+val[i], dp[j]);
12             }
13         }
14     }  

 

01背包问题可以再加一个例题:

https://www.luogu.com.cn/problem/P1802

1 for(int i=1;i<=n;i++){
2         for(int j=x1;j>=0;j--){
3             if(j>=b[i]){//如果有足够的药剂打赢别人,则看是输好还是赢好
4                 f[j]=max(f[j]+a[i][0],f[j-b[i]]+a[i][1]);
5             }
6             else f[j]+=a[i][0];//没有足够药剂就一个都不用直接认输,不然就浪费了药剂
7         }
8     }

 

 

 

 

 

 

2.完全背包(P1616)

这个与上一个的区别在于:这次的物品可以无限取.每种东西是不限量的.

代码的区别也很简单,这次是正着来的

https://www.luogu.com.cn/problem/P1616

1 for(int i=1;i<=n;i++)
2         for(int j=w[i];j<=V;j++)
3             f[j]=max(f[j],f[j-w[i]]+c[i]);

 

推荐阅读