http://noi.openjudge.cn/ch0207/4976/

描述

宇航员Bob有一天来到火星上,他有收集硬币的习惯。于是他将火星上所有面值的硬币都收集起来了,一共有n种,每种只有一个:面值分别为a1,a2… an。 Bob在机场看到了一个特别喜欢的礼物,想买来送给朋友Alice,这个礼物的价格是X元。Bob很想知道为了买这个礼物他的哪些硬币是必须被使用的,即Bob必须放弃收集好的哪些硬币种类。飞机场不提供找零,只接受恰好X元。

输入第一行包含两个正整数n和x。(1 <= n <= 200, 1 <= x <= 10000)
第二行从小到大为n个正整数a1, a2, a3 … an (1 <= ai <= x)输出第一行是一个整数,即有多少种硬币是必须被使用的。
第二行是这些必须使用的硬币的面值(从小到大排列)。


最朴素的方法是枚举每一种硬币,去掉这种硬币来计算X是否可达。这种n**3的算法会超时。

我们假设 f(x) 是用所有种类钱币组成 x 的方案数。假设 a[i] 是第 i 种硬币的价值。

f(x - a[i]) = (用到 a[i] 凑出价值 x - a[i] 的方案数) + (没用到 a[i] 凑出 x - a[i] 的方案数)

f(x)= (用到 a[i] 凑出价值 x 的方案数) + (没用到 a[i] 凑出 x 的方案数) = (没用到 a[i] 凑出 x - a[i] 的方案数) + (没用到 a[i] 凑出 x 的方案数)

我们再假设 g(x, i) 是没用到 a[i] 凑出 x 的方案数。

f(x) - f(x - a[i]) = (没用到 a[i] 凑出 x 的方案数) - (用到 a[i] 凑出价值 x - a[i] 的方案数) = g(x, i) - (f(x - a[i]) - g(x - a[i], i))

于是 f(x) = g(x, i) + g(x - a[i], i)

如果 g(x, i) = 0,即没用到 a[i] 凑出 x 的方案数是 0 的话,那么说明 a[i] 是必须被用到的。

我们只需要计算 g(x, i) = f(x) - f(x - a[i]) + f(x - 2 * a[i]) - ....

f(0) = 1,f(x) = 0 (x < 0)

于是我们只需要计算出 f(x) 就可以了,然后对于每个 i,判断 g(X, i) 是否为 0。

#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <limits.h>
#include <algorithm>
using namespace std; int X, coin[] = {};
vector<int> v; int calc(int f[], int i) {
int ret = f[X];
for (int j = ;; ++j) {
if (X - j * coin[i] < ) {
break;
}
int c = (j % == ? : -);
ret += c * (f[X - j * coin[i]]);
}
return ret;
} int main () {
int n;
cin >>n >>X;
int f[] = {};
for (int i = ; i < n; ++i) {
cin >>coin[i];
}
f[] = ;
for (int i = ; i < n; ++i) {
for (int j = X; j >= coin[i]; --j) {
f[j] += f[j - coin[i]];
}
}
int cnt = ;
for (int i = ; i < n; ++i) {
if (calc(f, i) == ) {
++cnt;
v.push_back(coin[i]);
}
}
cout <<cnt <<endl;
int sz = v.size();
for (int i = ; i < sz; ++i) {
cout <<v[i];
if (i == sz - ) {
cout <<endl;
} else {
cout <<" ";
}
}
}

OpenJudge NOI 4976 硬币的更多相关文章

  1. NOI 4976:硬币

    描述 宇航员Bob有一天来到火星上,他有收集硬币的习惯.于是他将火星上所有面值的硬币都收集起来了,一共有n种,每种只有一个:面值分别为a1,a2- an. Bob在机场看到了一个特别喜欢的礼物,想买来 ...

  2. openjudge noi 鸡尾酒疗法

    题目链接:http://noi.openjudge.cn/ch0105/18/ 总时间限制: 1000ms 内存限制: 65536kB 描述 鸡尾酒疗法,原指“高效抗逆转录病毒治疗”(HAART),由 ...

  3. openjudge noi 买房子

    题目链接:http://noi.openjudge.cn/ch0105/16/ 总时间限制: 1000ms 内存限制: 65536kB 描述 某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平 ...

  4. OpenJudge - NOI - 1.1编程基础之输入输出(C语言 全部题解)

    01:Hello, World! #include <stdio.h> int main(void) { printf("Hello, World!"); return ...

  5. 2016.4.3NOI上较难的动规题目(仔细分析样例)--王老师讲课整理

    1.NOI 191:钉子和小球 总时间限制: 1000ms 内存限制:  65536kB 描述 有一个三角形木板,竖直立放,上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1).每 ...

  6. 投入OJ的怀抱~~~~~~~~~~

    OpenJudge C20182024 信箱(1) 账号 修改设定 退出小组 管理员 frank 林舒 Dzx someone 李文新 公告 11-05 程序设计与算法(大学先修课) 成员(61910 ...

  7. 清北学堂2018DP&图论精讲班 DP部分学习笔记

    Day 1 上午 讲的挺基础的--不过还是有些地方不太明白 例1 给定一个数n,求将n划分成若干个正整数的方案数. 例2 数字三角形 例7 最长不下降子序列 以上太过于基础,不做深入讨论 例3 给定一 ...

  8. noi.openjudge 1.13.44

    http://noi.openjudge.cn/ch0113/44/ 总时间限制:  1000ms 内存限制:  65536kB 描述 将 p 进制 n 转换为 q 进制.p 和 q 的取值范围为[2 ...

  9. noi.openjudge 1.13.15

    http://noi.openjudge.cn/ch0113/15/ 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个长度为N的整数序列 (不多于128个整数),每个整数的范 ...

随机推荐

  1. linux下查询java进程以及杀掉其进程

    1.使用命令: ps -ef|grep java 查询到到自己想要kill掉的进程id 2.使用命令: kill -9 id(这里的id为你上一步查找到的id)

  2. python 0,1行列问题

    shape[0]-- 行 A.min(0) --A的按列最小值,生成一个行向量 >>> a = np.random.rand(3,3) >>> a array([[ ...

  3. php输出数据到csv文件

    function export() { $fileName = date('Y-m-d').uniqid().'.csv'; set_time_limit(0); ini_set('memory_li ...

  4. Vue-项目之免费课和购物车实现

    调整首页细节 固定头部 App.vue中代码 <style> body{ padding: 0; margin:0; margin-top: 80px; } </style> ...

  5. PS 给照片换背景

    1. 打开一张照片,导入证件照 2. 点击选择 => 选择并遮住 (快捷键 command + option + r) 3. 点击快速选择工具,将属性设置里面的视图模式选择为洋葱皮,鼠标点击需要 ...

  6. Day 05 可变不可变、数据类型内置方法

    1.可变类型:值改变,但是id不变,证明就是改变原值,是可变类型 2.不可变类型:值改变,但是id也跟着改变,证明是产生新的值,是不可变类型 数字类型 一.整型int 1.用途:记录年龄.等级.数量 ...

  7. win10系统IE浏览器中无法显示Java国际化的问题

    http://jingyan.baidu.com/article/656db918e37914e381249c9f.html?qq-pf-to=pcqq.c2c 自从装上Win10系统后,跟随前些IE ...

  8. Windows启动配置数据(BCD)存储文件包含一些无效信息

    Windows启动配置数据(BCD)存储文件包含一些无效信息-照牛排 http://www.zhaoniupai.com/archives/223.html 1)近来封装Windows 7,遇到挫折. ...

  9. 前端-JavaScript1-1——JavaScript简介

    1.1 JavaScript用途 前端三层: 结构层   HTML           从语义的角度描述页面的结构 样式层   CSS               从审美的角度装饰页面 行为层   J ...

  10. 随机森林RandomForest

    ID3,C4.5决策树的生成: 输入:训练集D,特征集A,阈值eps, 输出:决策树T 若D中所有样本属于同一类Ck,则T为单节点树,将类Ck作为该结点的类标记,返回T: 若A为空集,即没有特征作为划 ...