SWUN 才艺

才艺

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte

描述

说起才艺,YH最为得意的就是他的吃鸡之道。为了将其精湛的技艺传授给ACM的其他人,YH决定每天从机房带走一个人…..去吃鸡。YB经过千年的等待,终于等来了吃鸡的机会。正准备跨出机房之时,YB想起了一个关键的问题。这个吃鸡,到底是谁买单呢?于是YB便把他的疑虑跟YH提了出来。为了体现公平公正性,YH提出了一个游戏,让YB玩。如果YB能赢,则自己买单,否则就是YB买单。

游戏规则如下:

       有n堆硬币,每堆有Ai个硬币(1=<i<=n),,每堆硬币中有一个假币,假币比真币要重。YH给YB一个天平秤,YB可以通过使用秤来找到其中的假币,每次秤只能称同一堆的硬币。而且YH约定,每堆硬币中的假币价值为Vi(1=<i<=n),YB每找出一个假硬币,就能获得其价值。如果YB能在使用k次秤之后,获的总价值不少于m,则算YB赢。

 

强大的YB经过计算发现,有些情况是自己一定能赢的(也就是在说最坏的情况下也能赢)。如果自己一定能赢,鉴于YH良好的人品,YB会主动提出自己买单,然后一起去吃鸡。否则的话,也会因其不良的人品,不想与其共修此道,打算自己参悟,一个人去吃鸡。

输入

第一行有三个整数n(1<=n<=1000),k(0<=k<=1000),m(0<=m<=10000),分别以空格隔开。

第二行有n个整数,分别代表Ai;

第三个有n个整数,分别代表Vi;

其中,Ai,Vi都属于int型。

输出

若YB一定能赢,则输出”YB YH CJ”,否则输出”YB CJ”;

样例输入

5 0 62
1 1 1 1 1
2 4 8 16 32

5 4 62
2 2 2 2 2
2 4 8 16 32

样例输出

YB YH CJ
YB CJ

题目来源

PHK

http://218.194.91.48/acmhome/problemdetail.do?&method=showdetail&id=1228

这道题就是简单的背包问题,只不过进行小小的变形。

很明显的是这个题目求的是至多要称几次(因为要确定YB必须要赢),并且每堆至少有一个硬币。

所以当ai==0的时候,就确定是一个假硬币。两个的话,就要称一次。三个的话,就称两次就可以,天平两段各放一个硬币,如果相等,则表明剩下的那个是假硬币。

否则,说明质量大的为假硬币。

也就是说把总硬币分为三堆,只有这样的情况下,称的次数会最小。

3^0+1~3^1 最少为1

3^1~3^2   最少为2 

3^2~3^3  最少为3

.......

#include<iostream>
#include<stdio.h>
using namespace std;
int dp[10010],v[1010],c[1010];
struct node
{
	int a,v;
}tot[1010];
int main()
{
	int temp,i,j,n,k,z,m,sum,y;
	while(~scanf("%d%d%d",&n,&k,&m))
	{
		sum=0;
		for(i=0;i<n;i++)
			{
			scanf("%d",&temp);
			if(temp==1) tot[i].a=0;//用于cost的转化 	
			else
			{	
			y=0;
			while(temp!=0)
				{
				temp/=3;
				y++;
			 	} 
		tot[i].a=y;
			}
			}
		for(z=0,i=0;i<n;i++)
			{
			scanf("%d",&tot[i].v);
			if(tot[i].a==0)
			sum+=tot[i].v;
			else			//把不为0,转化为01背包的形式 
			{
			c[z]=tot[i].a;
			v[z++]=tot[i].v;
			}
			}
		if(sum>=m) cout<<"YB YH CJ"<<endl;//如果不用称就确定YB能赢,就直接输出 "YB YH CJ"
		else
		{
			memset(dp,0,sizeof(dp));
			for(i=0;i<z;i++)//简单的01背包 
				for(j=k;j>=c[i];j--)
				dp[j]=max(dp[j],dp[j-c[i]]+v[i]);
			if(dp[k]+sum>=m) cout<<"YB YH CJ"<<endl;
			else cout<<"YB CJ"<<endl;
		}
	}
	return 0;




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值