• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 博客园
  • 联系
  • 订阅
  • 管理

View Post

CodeForces 688E-The Values You Can Make

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

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

 

 

 

 

代码如下:

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <ctime>
 4 #include <vector>
 5 #include <cmath>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <algorithm>
11 #include <cstring>
12 
13 using namespace std;
14 
15 #define LL long long
16 #define INF 0x3f3f3f3f
17 #define MOD 1000000007
18 
19 const int maxn = 1e5+5;
20 int a[maxn],n,p;
21 int dp[505][505],tmp[505];
22 vector<int>ret;
23 
24 int main()
25 {
26     int i, j, k;
27 
28     while(scanf("%d%d",&n, &p)==2)
29     {
30         ret.clear();
31         for(i = 1; i <= n; i++ )
32           scanf("%d", &a[i]);
33         sort(a+1, a+1+n);
34         dp[0][0] = 1;   //dp[i][j]代表通过前i个元素和为i,能否组合出j
35         for(i = 1; i <= n; i++ )
36           for(j = p; j >= a[i]; j-- )
37             for(k = 0; k + a[i] <= p; k++ )
38                 if(dp[j-a[i]][k])
39                     dp[j][k] = dp[j][k+a[i]] = 1;
40         for(i = 0; i <= p; i++ )
41           if(dp[p][i])
42             ret.push_back(i);
43         printf("%d\n", ret.size());
44         for(i = 0; i < ret.size()-1; i++ )
45           printf("%d ", ret[i]);
46         printf("%d\n", ret[ret.size()-1]);
47     }
48 
49     return 0;
50 }

 

posted on 2016-07-14 11:30  tony-cao  阅读(247)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3