测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

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

填空题 较难

题目描述

硬币

宇航员 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 <= 10000)

输出

第一行是一个整数, 即有多少种硬币是必须被使用的。 第二行是这些必须使用的硬币的面值(从小到大排列) 。

样例输入

5 18

1 2 3 5 10

样例输出

2

5 10

提示

输入数据将保证给定面值的硬币中至少有一种组合能恰好能够支付 X元。 如果不存在必须被使用的硬币, 则第一行输出 0, 第二行输出空行。

参考答案

#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,a[21000],f[20010],x; int g[20010],num[20010]; int in() { int t=0; char ch=getchar(); while (ch>'9'||ch<'0') ch=getchar(); while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar(); return t; } main() { n=in();x=in(); for (int i=1;i<=n;i++) a[i]=in(); f[0]=1; for (int i=1;i<=n;i++) for (int j=x;j>=a[i];j--) f[j]+=f[j-a[i]]; //得出不去除硬币时的方案数 for (int i=1;i<=n;i++) { memset(g,0,sizeof(g)); for (int j=0;j<=x;j++) if (j-a[i]>=0) g[j]=f[j]-g[j-a[i]]; else g[j]=f[j]; if (g[x]==0) num[++num[0]]=a[i]; } printf("%d\n",num[0]); for (int i=1;i<=num[0];i++) printf("%d ",num[i]); }
上一题 下一题