花生米三连发(动规)

1.时限:1000ms 内存限制:10000K  总时限:3000ms
描述
五一长假第二天,Tom和Jerry在仓库散步的时候又发现了一堆花生米(这个仓库还真奇怪)。这次Tom制定分花生米规则如下:
       1、Tom和Jerry轮流从堆中取出k粒花生米吃掉,k可以是1,5,10中的任意一个数字;
       2、为显示规则的公平性,Jerry可以选择先取或者后取。
Jerry当然还是希望最后一粒花生米被Tom吃掉。请计算,Jerry为了达到目的应该先取还是后取。
 
输入
本题有多个测例,每个测例的输入是一个整数n,n大于零小于等于1000,代表花生米的数量。
n等于0表示输入结束,不需要处理。
 
输出
每个测例在单独的一行内输出一个整数:Jerry先取输出1;Tom先取输出0。
 
输入样例
1
2
3
4
0
 
输出样例
0
1
0
1
 
提示
 
来源

2.时限:1000ms 内存限制:10000K  总时限:3000ms
描述
五一长假第三天,Tom和Jerry在仓库散步的时候又发现了一堆花生米(仓库,又见仓库……)。这次Tom制定分花生米规则如下:
???????1、Tom和Jerry轮流从堆中取出k粒花生米吃掉;
2、第一次取花生米的人只能取一粒,以后取花生米的数量不能超过前一个人取花生米数量的两倍;
3、为显示规则的公平性,Jerry可以选择先取或者后取。
Jerry当然还是希望最后一粒花生米被Tom吃掉。请计算,Jerry为了达到目的应该先取还是后取。
 
输入
本题有多个测例,每个测例的输入是一个整数n,n大于零小于等于1000,代表花生米的数量。
n等于0表示输入结束,不需要处理。
 
输出
每个测例在单独的一行内输出一个整数:Jerry先取输出1;Tom先取输出0。
 
输入样例
1
2
3
4
5
0
 
输出样例
0
1
0
0
1
 
提示
 
来源

3.时限: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
 
提示
 
来源
 

三道题都是相似的动态规划,在考虑第i步的策略的时候要考虑前几步的状态。
要注意的是,如果前几步全是JERRY赢,那么这一步让TOM来去,如果有TOM赢得可能,那就必须JERRY取,因为TOM是在乱取的,而JERRY是有策略的。

#include <iostream>
#include <stdio.h>

int main()//1
{
	int i, n;
	bool dp[1002];//tom是ture,jerry是false
	dp[1] = true;
	i = 2;
	for (i = 2; i <= 1000; i++)
	{
			if (i - 1 >= 1 && i - 5 < 1)
			{
				if (dp[i - 1] == false)
				{
					dp[i] = true;
				}
				else
				{
					dp[i] = false;
				}
			}
			else if (i - 5 >= 1 && i - 10 < 1)
			{
				if (dp[i - 1] == false && dp[i - 5] == false)
				{
					dp[i] = true;
				}
				else
				{
					dp[i] = false;
				}
			}
			else if (i - 10 >= 1)
			{
				if (dp[i - 1] == false && dp[i - 5] == false && dp[i - 10] == false)
				{
					dp[i] = true;
				}
				else
				{
					dp[i] = false;
				}
			}
	}
	while (1)
	{
		scanf("%d", &n);
		if (n == 0)
		{
			break;
		}
		else
		{
			if (dp[n] == true)
			{
				printf("0\n");
			}
			else
			{
				printf("1\n");
			}
		}
	}
	return 0;
}
#include <stdio.h>
#include <iostream>

using  namespace std;//2

bool dp[2002][2002];//tom为true,jerry为false

void figure(int a, int b)
{
	int i, flag;
	if (b == 1)
	{
		if (dp[a - 1][2] == false)
		{
			dp[a][1] = true;
		}
		else
		{
			dp[a][1] = false;
		}
	}
	else if (a == b + 1)//刚好位于对角线下一格的话依然jerry,因为dp[n][n-1]总能跳转到tom上
	{
		dp[a][b] = false;
	}
	else if (b>1)
	{
		flag = 0;
		for (i = 1; i <= b && 2 * i < a; i++)
		{
			if (dp[a - i][2 * i] == true)//状态转移到了tom上
			{
				flag = 1;
				dp[a][b] = false;
				break;
			}
		}
		if (flag == 0)//状态转移不到tom上
		{
			dp[a][b] = true;
		}
	}
	return;
}

int main()
{
	int i, j, n;
	for (i = 1; i <= 1001; i++)
	{
		dp[i][i] = false;//对角线全jerry
		dp[1][i] = true;
		dp[2][i] = false;
	}
	for (i = 3; i <= 1000; i++)
	{
		for (j = 1; j < i; j++)
		{
			figure(i, j);//探讨dp[i][j]的状态
		}
	}
	while (1)
	{
		scanf("%d", &n);
		if (n == 0)
		{
			break;
		}
		else
		{
			if (dp[n][1] == true)
			{
				printf("0\n");
			}
			else
			{
				printf("1\n");
			}
		}
	}
	return 0;
}
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;//3

char dp[10002];

int main()
{
	int i, n, die, k, flag, j;
	double x;
	while (1)
	{
		memset(dp, 0, sizeof(dp));
		scanf("%lf", &x);
		if (x < 0)
		{
			break;
		}
		n = (int)(x * 10);
		if (n <= 10)
		{
			printf("1\n");
			continue;
		}
		die = n / 2;
		for (i = 1; i <= die - 1 ; i++)
		{
			dp[i] = 'T';//低于花生酱数量一半的应该全都是tom
		}
		if (n % 2 == 1)
		{
			dp[i] = 'T';
		}
		else
		{
			dp[i] = 'J';
		}
		for (i = die + 1; i <= n - 10; i++)
		{
			k = n - i;//k表示已经吃掉的数量
			flag = 0;//先假设没找到T
			if (i <= 3 * k)
			{
				for (j = 1; j <= i - k; j++)
				{
					if (dp[j] == 'T')
					{
						flag = 1;//找到了T
						dp[i] = 'J';
						break;
					}
				}
			}
			else
			{
				for (j = i - 3 * k; j <= i - k ; j++)
				{
					if (dp[j] == 'T')
					{
						flag = 1;
						dp[i] = 'J';
						break;
					}
				}
			}
			if (flag == 0)
			{
				dp[i] = 'T';
			}
		}
		if (dp[n - 10] == 'T')
		{
			printf("1\n");
		}
		else if (dp[n - 10] == 'J')
		{
			printf("0\n");
		}
	}
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
花生米AJAX-UI系列之:基于JQUERY的GooPanel窗体控件类0.1版 (从今起,以后所有的新控件均使用JQUERY 1.5以上的内核) 特点: 1、既可当浮动窗口用,也可以当作网页中的内容容器框使用。 2、具备relative,absolute两种定位方式,和两种风格。 3、不仅有“关闭、最大化/还原、最小化、收起/下拉,固定最前端”等默认的右上角功能按钮,用户还可自定义排列顺序以及自定设定的按钮。 4、支持手工调整大小,手工移动。 5、内容可以是从AJAX远端载入的内容,也可以是本页面中的一个DOM元素,也可以是嵌入一个iframe。 6、可以把移动的窗体限制在父框架可见的范围内, 也可以让窗体超出父框架显示。 7、使用单个或少数几个窗体时,可分别定义单独的GooPanel类对象;当使用多个窗体时或者在随时可能增减窗体的情况下时,就可用到GooPanelManager管理类 8、使用GooPanelManager管理类时,STICK功能状态(即把窗体固定在最前顶(z-index保持最大))才会有效. 9、用户可以自定义右上角功能按钮点击时,另外要执行的事件方法。 10、用户可以自定义当“重定义窗体宽高”、“重定义绝对定位”、“重设置Z-INDEX值”时分别发生的事件方法。其中绑定“重定义窗体宽高”事件很有用,比如用在窗体尺寸变化后,将内容框里的DOM元素重新Resize. 本品兼容IE6--IE8 ,firefox,chrome浏览器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值