您的位置:首页 > 产品设计 > UI/UE

CodeForces 688E-The Values You Can Make

2016-07-14 11:30 399 查看
题意:
  给出n,k,分别代表硬币的数量与巧克力的价格,n个整数c1,c2,...ci...cn(ci代表第i块硬币的值);你可以从n块硬币中拿出金额恰好为k的硬币数并将其中的任意两块硬币组合得到一个数,将其保存下来(0和输入的n个数的值也必须被保存),最后将这些数按升序排列输出.

分析:
  可以采用dp的递推方法,从1到n,dp[i][j]代表通过前i个元素和为i,能否组合出j.

代码如下:

#include <cstdio>
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007

const int maxn = 1e5+5;
int a[maxn],n,p;
int dp[505][505],tmp[505];
vector<int>ret;

int main()
{
int i, j, k;

while(scanf("%d%d",&n, &p)==2)
{
ret.clear();
for(i = 1; i <= n; i++ )
scanf("%d", &a[i]);
sort(a+1, a+1+n);
dp[0][0] = 1;   //dp[i][j]代表通过前i个元素和为i,能否组合出j
for(i = 1; i <= n; i++ )
for(j = p; j >= a[i]; j-- )
for(k = 0; k + a[i] <= p; k++ )
if(dp[j-a[i]][k])
dp[j][k] = dp[j][k+a[i]] = 1;
for(i = 0; i <= p; i++ )
if(dp[p][i])
ret.push_back(i);
printf("%d\n", ret.size());
for(i = 0; i < ret.size()-1; i++ )
printf("%d ", ret[i]);
printf("%d\n", ret[ret.size()-1]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: