田忌赛马——贪心正确性证明

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
32.{
33.Байду номын сангаасon++;
34.st--;
35.sk--;
36.}
37.elseif(tian[st] < king[sk])
38.{
39.mon--;
40.sk--;
41.et++;
42.}
43.else
44.{
45.if(tian[et] > king[ek])
46.{
47.mon++;
48.et++;
3.当田忌最慢的和齐王最慢的马慢相等时,分4和5讨论。
4.当田忌最快的马比齐王最快的马快时,赢一场先。因为最快的马的用途就是来赢别人快的马,别人慢的马什么马都能赢。
5.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场,因为反正要输一场,不如拿最没用的马输。
6.当田忌最快的马和齐王最快的马相等时,这就要展开讨论了,贪心方法是,拿最慢的马来和齐王最快的马比.
程序如下:
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
int x,y;
x=*(int *)a;
y=*(int *)b;
if (x<y)
return 1;
else if (x>y)
return -1;
else return 0;
}
int main()
{
int n;
while (scanf("%d", &n)!=EOF)
{
if (n == 0)
break;
int *tian = new int[n];
int *king = new int[n];
for (int i = 0; i < n; i++)
scanf("%d", &tian[i]);
}
int main()
{
int i,j,k,s,x,n,t[1000],q[1000];
scanf("%d",&n);
while (n!=0)
{
for (i=0;i<n;i++)
scanf("%d",&t[i]);
for (i=0;i<n;i++)
scanf("%d",&q[i]);
qsort(t,n,sizeof(t[0]),cmp);
int sum=0;
while(tl<=tr)
{
if(a[tl]<b[ql])
{
qr--;
tl++;
sum=sum-200;
}
else if(a[tl]==b[ql])
{
while(tl<=tr&&ql<=qr)
{
if(a[tr]>b[qr])
{
sum+=200;
tr--;
qr--;
}
else
{
if(a[tl]<b[qr]) sum-=200;
ek -= 1;
}
else if (tian[et] < king[ek])
{
mon -= 1;
et -= 1;
sk += 1;
}
else
{
if (tian[et] < king[sk])
mon -= 1;
et -= 1;
sk += 1;
}
}
}
printf("%d\n", mon*200);
}
return 0;
#include <iostream>
using namespace std;
void sort(int a[], int n)
{
for (int i = 0; i < n-1; i++)
for (int j = i+1; j < n; j++)
if (a[j] > a[i])
swap(a[j], a[i]);
while(scanf("%d",&n),n)
{
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
for(int i=1; i<=n; i++) scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+n);
int tl=1,tr=n,ql=1,qr=n;
20.
21.sort(tian,tian+n);
22.sort(king,king+n);
23.intst = n-1;
24.intsk = n-1;
25.intet = 0;
26.intek = 0;
27.intmon = 0;
28.
29.for(i = 0; i < n; i++)
30.{
31.if(tian[st] > king[sk])
11.break;
12.
13.int*tian =newint[n];
14.int*king =newint[n];
15.
16.for(i = 0; i < n; i++)
17.scanf("%d", &tian[i]);
18.for(i = 0; i < n; i++)
19.scanf("%d", &king[i]);
}
http://acm.pku.edu.cn/JudgeOnline/problem?id=2287
这是2004上海两道最简单的题之一,但我做这题时用了两个半小时,其实如果一开始就采用最后的算法的话也是15分钟就通过了.唉,首先是将田忌的马和齐王的马分别进行排序,然后在齐王的序列中找到田忌最快的马的位置,它之前有几匹马那田忌就至少输掉几场比赛,然后开始枚举最终输掉的场次,将田忌最慢的马与齐王最好的马比赛,剩下的马一一对应比赛,找出赢钱的最大值就可以了.我希望直接用算法找到最后的结果,想了2个多小时也没有结果,最后在问题规模不大的情况用了这样的方法.没办法啊.
1.b1=b2,an=an+1
则有
a2 a3 a4...an
b2 b3 b4...bn
其中a2>=a1,a1=b1,b1=b2,得a2>=b2(此后这种大小关系不再论述),an>=bn.
此时若a2=b1,根据归纳假设,有最优解,否则a2>根据前面“公理”论证有最优解。
当且仅当a数列,b数列元素全部相等时有an+1=b1,已证得,所以an+1>b1,赢回最慢的马来和齐王最快的马比输的那一场。
qsort(q,n,sizeof(q[0]),cmp);
for (i=0;t[0]<q[i] && i<n;i++);
for (s=-200*n;i<n;i++)
{
x=-i*200;
for (j=i,k=0;j<n;j++,k++)
就赶紧把我的思路贴出来吧哈
我的思路是:
如果最慢的马不同:1 . TJ快,TJ最慢拼掉QW最慢。2 . TJ慢,TJ最慢拼掉QW最快。
如果最快的马不同:1 . TJ快,TJ最快拼掉QW最快。2 . TJ慢,TJ最慢拼掉QW最快。
若最快最慢都相同:TJ最慢拼掉QW最快。
my code : only for reference ^_^
49.ek++;
50.}
51.elseif(tian[et] < king[ek])
52.{
53.mon--;
54.et++;
55.sk--;
56.}
57.else
58.{
59.if(tian[et] < king[sk])
60.mon--;
61.et++;
62.sk--;
63.}
64.}
65.}
66.
tl++;
qr--;
break;
}
}
}
else
{
tl++;
ql++;
sum=sum+200;
}
}
printf("%d\n",sum);
}
return 0;
}
一道不错的贪心题不过ms贪心的本质比较难把握至少对我自己来说是这样子滴~愣了N久硬是没愣出来抓狂中~~
不过今天早上RP好终于啃下这块骨头啦哈难得~
67.printf("%d/n", mon*200);
68.}
69.return0;
70.}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1010],b[1010];
int main()
{
int n;
{
if (tian[st] > king[sk])
{
mon += 1;
st += 1;
sk += 1;
}
else if (tian[st] < king[sk])
{
mon -= 1;
sk += 1;
et -= 1;
}
else
{
if (tian[et] > king[ek])
{
mon += 1;
et -= 1;
zju2397 hdu1052田忌赛马贪心正确性证明
算法可以用DP,或者给每匹马连线赋权变为二分图最佳匹配,还有就是贪心了。
1.当田忌最慢的马比齐王最慢的马快,赢一场先
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场
3.当田忌最快的马比齐王最快的马快时,赢一场先。
4.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场。
2.b1<=b2,an=an+1
交换b1,b2的位置,
数列
(a1) a2 a3 a4...an an+1
b2 b1 b3 b4...bn (bn+1)
此时a2>=a1,an>=bn,
对于子表
a2 a3 a4...an
b1 b3 b4...bn
根据前面“公理”或归纳假设,有最优解。
an+1>=b2,当且仅当b2=b3=b4=..=bn+1时有an+1=b2,这种情况,a中其它元素<=b1,b2,b3,b4..bn,对于这部分来说,能赢x盘(x<=n),假如不拿最慢的马来和齐王最快的马比则拿最快的马来和齐王最快的马比,此时平一盘,能赢x-1盘,而拿最慢的马来和齐王最快的马比,输一盘能赢x盘,总的来说,还是X这个数,没有亏。
数列
a1 a2 a3 a4...an an+1
b1 b2 b3 b4...bn bn+1
其中ai>=ai-1,bi>=bi-1
数列a和数列b不全部相等时,拿最慢的马来和齐王最快的马比数列得到数列
(a1) a2 a3 a4...an an+1
b1 b2 b3 b4...bn (bn+1)
分4种情况讨论
3.b1=b2,an<=an+1
4.b1<=b2,an<=an+1证明方法类似,不再重复。
以证得当有n+1匹马的时候,田忌和齐王最快最慢的马速度相等时,拿最慢的马来和齐王最快的马比有最优解,已知当n=2时成立,所以对于n>2且为整数(废话,马的只数当然是整数)时也成立。当n=1时....这个似乎不用讨论.
2)当数列a和数列b全部相等等时(a1=b1,a2=b2...an=bn),显然最慢的马来和齐王最快的马比有最优解,可以赢n-1长,输1场,找不到更好的方
法了。
3)当数列a和数列b元素全部相等时(a1=b1=a2=b2...=an=bn),无法赢也不输。
现在假设n匹马时拿最慢的马来和齐王最快的马比有最优解,证明有n+1匹马时拿最慢的马来和齐王最快的马比也有最优解。
5.当田忌最快的马和齐王最快的马相等时,拿最慢的马来和齐王最快的马比.
田忌赛马贪心的正确性证明。
先说简单状况下的证明:
1.当田忌最慢的马比齐王最慢的马快,赢一场先。因为始终要赢齐王最慢的马,不如用最没用的马来赢它。
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场。因为田忌最慢的马始终要输的,不如用它来消耗齐王最有用的马。
for (int i = 0; i < n; i++)
scanf("%d", &king[i]);
sort(tian, n);
sort(king, n);
int st = 0;
int sk = 0;
int et = n-1;
int ek = n-1;
int mon = 0;
for (int i = 0; i < n; i++)
前面的证明像公理样的,大家一看都能认同的,没有异议的,就不细说了。
证明:田忌最快的马和齐王最快的马相等时拿最慢的马来和齐王最快的马比有最优解。
1)假设他们有n匹马,看n=2的时候.
a1 a2
b1 b2
因为田忌最快的马和齐王最快的马相等所以a1=b1,a2=b2所以这种情况有2种比赛方式,易得这两种方式得分相等。
2711203 2007-12-23 11:03:04 Accepted 2397 FPC 00:00.07 424K liukai
解题思路:
贪心算法:
先比最快的马:1、如果TJ的马快,先将TJ最快和K的最快马比。2、如果TJ的马慢,则用TJ的最慢马和K的最快马比。
如果最快的马相等,再比最慢的马:1、如果TJ的马快,先将TJ的最慢马和K的最慢马比。2、如果TJ的马慢,则用TJ的最慢马和K的最快马比。
如果最快最慢的马都一样,则用TJ的最慢马和K的最快马比。
1.#include <iostream>
2.#include <algorithm>
3.usingnamespacestd;
4.
5.intmain()
6.{
7.intn,i;
8.while(scanf("%d", &n)!=EOF)
9.{
10.if(n == 0)
相关文档
最新文档