中等·Magry摆什锦糖 buaacoding DP 动态规划

    这道题是一道简单的动态规划的问题,题目大意是利用n个数来判断是否可以组成一个值为k的数字

  这道题可以利用必须装满的01背包思路来解释,另一方面也可以利用另一种思路来思考,直接从答案入手,定义dp数组DP【i】【j】那么这个数组所代表的意思就是前i个数是否可以组成值为j的数。由于dp的值只有两个,于是我们可以利用bool类型来节约空间。另一方面,动态规划问题处理的核心只有三个,首先要确定一个有特殊含义的方程,然后是状态转移方程,最后不容忽视的是初始化问题,因为所有的状态转移方程都是基于初值给定的。

这道题的状态转移方程可以描述为:

1          if(j>=ar[i])
2                     dp[i][j]=dp[i-1][j] || dp[i-1][j-ar[i]];
3                 else 
4             dp[i][j]=dp[i-1][j];

具体的初始化细节是:

1         memset(dp,0,sizeof(dp));
2         for(i=1;i<=n;i++)
3             dp[i][0]=1;

最后完整的AC代码是:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <string.h>
 4 using namespace std;
 5 const int Maxlen=510;
 6 bool dp[Maxlen][Maxlen];
 7 //其中dp[i][j] 代表的是前i种糖果是否可以组成美味程度为j的什锦糖
 8 int main(){
 9     int n,k,i,j;
10     int ar[Maxlen];
11     // 动态规划
12     while(~scanf("%d %d",&n,&k)){
13         for(i=1;i<=n;i++)
14             scanf("%d",&ar[i]);
15         //DP数组的初始化
16         memset(dp,0,sizeof(dp));
17         for(i=1;i<=n;i++)
18             dp[i][0]=1;
19         for(i=1;i<=n;i++)
20             for(j=1;j<=k;j++)
21                 if(j>=ar[i])
22                     dp[i][j]=dp[i-1][j] || dp[i-1][j-ar[i]];
23                 else dp[i][j]=dp[i-1][j];
24         if(dp[n][k] == true)
25             printf("Yes\n");
26         else printf("No\n");
27     }
28     return 0;
29 }

 

posted on 2018-12-04 16:46  Visper  阅读(173)  评论(0编辑  收藏  举报