原博客:花生米5
花生米(五)
时限:1000ms 内存限制:10000K 总时限:3000ms
描述:
五一长假第六天,Tom在QQ上遇到了Kitty。呵呵,Kitty,在离散数学课上认识的PPMM……等等!Tom恍然大悟:自己这一生除了看帖不回之外最大的错误就是离散数学没学好!
五一长假第七天,Tom和Jerry在仓库散步的时候发现了一堆花生米(仓库,呵呵,仓库…)。这次Tom制定分花生米规则如下:
1、首先选出最苦的一粒花生米,放到一个瓶子里;
2、把剩下的花生米做成花生酱,Tom和Jerry轮流取一些花生酱吃掉;
3、第一个取的人只能取1.0克,以后取花生酱的数量不能少于两个人已经取过的总数量且不能超过两个人已经取过的总数量的三倍;
4、不能按规则3取花生酱的人必须吃掉瓶子里的花生米;
5、为显示规则的公平性,Jerry可以选择先取或者后取。
Jerry当然希望瓶子里的花生米被Tom吃掉。请计算,Jerry为了达到目的应该先取还是后取。
输入:
本题有多个测例,每个测例的输入是一个浮点数w,w大于1.0小于等于1000.0,w最多只有一位小数,代表花生酱的数量,单位为克。
w小于0表示输入结束,不需要处理。
输出:
每个测例在单独的一行内输出一个整数:Jerry先取输出1;Tom先取输出0。
输入样例:
1.5
7.9
-1
输出样例:
1
0
这也是一个动态规划的问题。
#include <stdio.h>
int a[10001];
float m;
int n;
int search();
int main(){
int an;
scanf("%f",&m);
n=m*10;
while(n>=0){
an=search();
if(an)printf("0\n");
else printf("1\n");
scanf("%f",&m);
n=m*10;
}
}
int search(){
int i,j,k,flag;
for(i=0;i<10001;i++) a[i]=0;
for(i=n;i>9;i--){//i表示已经吃了i个,最小取1.0克,又放大了10倍,所以大于9
flag=0;
j=n-i;//剩下j了
if(i>j) a[i]=0;//此时,已取的大于未取的,那么未来再次取的时候不满足条件3,故会吃掉苦的花生米,会输,所以让Tom取
else{
if(j<=3*i) a[i]=1;//此时,再取的时候还可以满足条件3,所以,可让Jerry取。
else{
for(k=i;k<=3*i;k++){//每次取的个数不能小于两人已经取过的总数量,所以从i开始
if(a[i+k]==0){flag=1;break;}//未来有某种情况让Tom取时Jerry会赢,所以此刻可以让Jerry取适量的花生米以达到那种情况。
}
if(flag==1) a[i]=1;
else a[i]=0;
}
}
}
return a[10];
}