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. RabbitMQ安装记录(windows10)

    RabbitMQ安装记录(windows10)   一.安装包准备 otp_win64_R16B03.exe(这里使用该版本,不支持ssl) otp_win64_19.0.exe(如果要开启ssl,请 ...

  2. 《Linux内核原理与分析》第三周作业

    实验:基于kernel的简单的时间片轮转多道程序内核 1.实验要求 完成一个简单的时间片轮转多道程序内核代码 2.实验过程 进入实验楼的linux环境,打开shell,输入以下代码: cd Linux ...

  3. [ Codeforces Round #549 (Div. 2)][D. The Beatles][exgcd]

    https://codeforces.com/contest/1143/problem/D D. The Beatles time limit per test 1 second memory lim ...

  4. Centos7 下安装VMware tools

    1:先在虚拟机点击安装VMware Tools   2:然后挂载       mount /dev/cdrom /mnt 3:进入/mnt,可以看到有       4:拷贝VMwareTools到其他 ...

  5. 深入分析JavaWeb Item2 -- Tomcat服务器学习和使用

    https://segmentfault.com/a/1190000004095363 一.Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件 ...

  6. nginx gzip配置

    参考: https://docs.nginx.com/nginx/admin-guide/web-server/compression/ server { gzip on;    gzip_types ...

  7. new 对象时的暗执行顺序

    为什么称为暗执行顺序,因为当我们在new 对象时,其不是简简单单的new一个完事,它要首先检查父类的,静态的,非静态的等代码,就好像我们结婚生孩子一样,要先到祖宗那里,公安局那里,左邻右舍那里,告诉他 ...

  8. WINDOWS NT操作系统的注册表文件

    WINDOWS NT操作系统的注册表文件 WINDOWS NT注册表文件分为系统文件和用户文件两类. 系统设置和缺少用户 配置数据存放在系统C:\Windows\System32\config文件夹下 ...

  9. fastext 中文文本分类

    1. 输入文本预处理, 通过jieba分词, 空格" "拼接文本串.  每行一个样本, 最后一个单词为双下划线表明label,  __label__'xxx' . eg: 邱县 继 ...

  10. cookie and sesssion

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...