• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
CoderForces 687C The Values You Can Make (01背包,DP)

题意:给定 n 个硬币和一个值 k,问你在用一些硬币组成面值为 k的这些硬币还能组成多少种其他面值。

析:如果这样说,由这些硬币能组成多少种不同的面值,那么是不是就很熟悉了,这不就是01背包么,这个题又加了一个限制条件,是用能组成 k 的这些硬币,也是类似的,d[i][j],表示硬币 j 能组成面值 i,

那么如果再加一个硬币x,d[i+x][j]也是可以的,d[i+x][j+x]也是可以的,所以如果d[i][j]成立,那么d[i+x][j],和d[i+x][j+x]也是成立的。

代码如下:

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
const int maxn = 500 + 5;
vector<int> ans;
bool d[maxn][maxn];

int main(){
    int n, k, x;
    while(scanf("%d %d", &n, &k) == 2){
        ans.clear();
        memset(d, 0, sizeof(d));
        d[0][0] = true;
        for(int i = 0; i < n; ++i){
            scanf("%d", &x);
            for(int j = k; j >= x; --j)
                for(int l = 0; l + x <= k; ++l)
                    if(d[j-x][l])  d[j][l] = d[j][l+x] = true;
        }
        for(int i = 0; i <= k; ++i) if(d[k][i])  ans.push_back(i);
        printf("%d\n", ans.size());
        for(int i = 0; i < ans.size(); ++i)  if(!i)  printf("%d", ans[i]);
            else  printf(" %d", ans[i]);
        printf("\n");
    }
    return 0;
}

 

posted on 2016-07-07 13:10  dwtfukgv  阅读(156)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3