这道题是一道简单的动态规划的问题,题目大意是利用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 "); 26 else printf("No "); 27 } 28 return 0; 29 }