博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
a.Baby Coins
阅读量:4331 次
发布时间:2019-06-06

本文共 1641 字,大约阅读时间需要 5 分钟。

a: Baby Coins

Time Limit: 1 Sec  Memory Limit: 128 MB

Description

Baby 今天清点自己的百宝箱啦,箱子里有 n 种硬币,硬币的面值分别是:val[1],val[2],...,val[n],每种面值的硬币都恰好有 2 个。Baby 实在闲的太无聊了,他想从他所拥有的硬币中选出若干个,使得面值之和为 k。那么他的目标能否实现呢 ~

Input

每一组数据第一行都包含两个数字 n(n≤18),k(1≤k≤1e9)。n 代表箱子中所包含的硬币种数,k 代表 Baby 需要组成的金钱数额。接下来的一行代表 val[1],val[2],......,val[n]。(1≤val[i]≤ 1e7)

Output

如果Baby能组成金钱数额k,请输出Yes,否则输出No。

Sample Input

22 103 43 91 2 10

Sample Output

Case 1: YesCase 2: No   折半枚举,先假设每种硬币只能选一次,枚举出所有可能性的和存到一个数组里(O(n*2^n)),然后把数组排序二分查找,比如一种可能性是a[i],那我们只要看k-a[i]是不是也在这个数组里就行了。
1 #include
2 #include
3 using namespace std; 4 #define rd(a) scanf("%d",&a) 5 #define rep(i,a,b) for(int i=(a);i<=(b);i++) 6 int v[25],a[300000]; 7 int main(){ 8 int T; 9 rd(T);10 rep(tt,1,T){11 int n,k;12 rd(n);rd(k);13 for(int i=0;i
View Code
 

 

 经过大佬指点之后发现还可以换一种思路枚举,这里我们把硬币平均分成前后两组,每一组分别枚举取0,1,2枚硬币的状态(O(n*3^(n/2))),然后在前后两组用二分找是否有和为k的就行了。
1 #include
2 #include
3 using namespace std; 4 #define rd(a) scanf("%d",&a) 5 #define rep(i,a,b) for(int i=(a);i<=(b);i++) 6 int v[25],a[20000],b[20000],sum,pow3[20]={
1}; 7 bool judge(int n,int k){ 8 if(sum
=0;j--){13 while(t>=pow3[j])14 tot+=v[j],t-=pow3[j];15 }16 if(tot==k)return 1;17 if(tot
=n/2;j--){22 while(t>=pow3[j-n/2])23 tot+=v[j],t-=pow3[j-n/2];24 }25 if(tot==k)return 1;26 if(tot
View Code
 

 

 

转载于:https://www.cnblogs.com/KafuuMegumi/p/10090646.html

你可能感兴趣的文章
P1313 计算系数
查看>>
NSString的长度比较方法(一)
查看>>
Azure云服务托管恶意软件
查看>>
My安卓知识6--关于把项目从androidstudio工程转成eclipse工程并导成jar包
查看>>
旧的起点(开园说明)
查看>>
生产订单“生产线别”带入生产入库单
查看>>
crontab导致磁盘空间满问题的解决
查看>>
java基础 第十一章(多态、抽象类、接口、包装类、String)
查看>>
Hadoop 服务器配置的副本数量 管不了客户端
查看>>
欧建新之死
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>
笛卡尔遗传规划Cartesian Genetic Programming (CGP)简单理解(1)
查看>>
mysql 日期时间运算函数(转)
查看>>
初识前端作业1
查看>>
ffmpeg格式转换命令
查看>>
万方数据知识平台 TFHpple +Xpath解析
查看>>
Hive实现oracle的Minus函数
查看>>
秒杀多线程第四篇 一个经典的多线程同步问题
查看>>
RocketMQ配置
查看>>