您的位置:首页 > 其它

海盗分金币

2016-05-04 20:31 232 查看
问题描述

有n个海盗,得到了m个金币。他们决定将之瓜分。分的方法是站成一排,从1号到n号海盗依次提出方案。如果提出的方案得到的支持人数比例超过Q%(0<=Q<100),那么就通过方案,进行分配,提出方案的海盗也有投票权。否则就把提出方案的人扔到海里喂鲨鱼。

海盗都是精明的,他们能够分析出如何最大化自己的利益。
海盗是贪婪的,总是选择更大的利益。
海盗是邪恶的,如果利益相同,更愿意杀人。
输入n,m,Q,问第一个人最多可能得到多少金币。如果必死无疑,输出-1.
n<=10000, m<=1000000000
样例解析:
当有一个人的时候,他能够拿到所有的100个金币。
当有两个人的时候,后一个人永远不会同意前一人的方案,即必死无疑,等于-1。
当有三个人的时候,第一人选择自己拿走100个,其他人不给。此时第二人如果不支持,就必死,故一定会支持。
当有四、五个人的时候,分配方案如下:
1个人:100

2个人:100 -1

3个人: 0 0 100

4个人: 1 1 0 98

5个人: 2 0 1 0 97

测试输入

期待的输出

时间限制

内存限制

额外进程

测试用例 1以文本方式显示

5 100 50↵

以文本方式显示

97↵

1秒64M0
题解思路

大致思路;

因为每个人都是聪明绝顶的,并且是残忍的,所以第一个人知道后面所有人的方案,所以第一个人要想使自己的方案被采纳就必须要贿赂其他的n*p/100个人才行。贿赂的时候就找最好贿赂的人进行贿赂。

具体实现:

从1个人递推到n个人,对于每一次的递推,先判断新加入的人是否会死,然后如果不会死的话就将要贿赂的人的期望加1,其他的人的期望赋为0,然后排序,将期望小的放在最前面方便下一次贿赂。

注意:

由于时间限制,所以排序的时候需要注意。我们在排序的时候发现,每次需要排序的都是两个有序的序列,所以我们只需要把这两个序列交换一下位置就可以了,这样从1开始每次都是这样有序排的,可以节省很多时间。

实现代码

<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int n,q;
long m;
int i,huilu,sum,j,temp1,temp2,k,l;
int a[10001];
memset(a,0,sizeof(a));
scanf("%d%d%d",&n,&m,&q);
if(n==1)
{
printf("%d\n",m);
}
else
{
for(i=1;i<=n;i++)
{
huilu=0;
sum=0;
if(i==1)
{
a[0]=m;
}
else if(i!=n)
{
huilu=i*q/100;
for(j=1;j<=huilu;j++)
{
sum+=a[j-1]+1;
}
if(sum>m)
{
for(k=0;k<i-1;k++)
{
a[i-1-k]=a[i-2-k];
}
a[0]=-1;
}
else
{
for(j=1;j<=huilu;j++)
{
a[j-1]=a[j-1]+1;
}
for(k=1;k<=huilu;k++)
{
a[i-1-k]=a[huilu-k];
}
for(j=huilu+1,k=0;j<i;j++,k++)
{
a[k]=0;
}
a[i-1]=m-sum;
temp1=a[i-1];
for(k=i-2;k>0;k--)
{
if(a[k]<=temp1)
{
for(l=i-2;l<=k+1;l++)
{
a[l+1]=a[l];
}
a[k+1]=temp1;
break;
}
}
}
}
else
{
huilu=i*q/100;
for(j=1;j<=huilu;j++)
{
sum+=a[j-1]+1;
}
if(sum>m)
{
printf("-1\n");
}
else
{
for(j=1;j<=huilu;j++)
{
a[j-1]=a[j-1]+1;
}
for(k=1;k<=huilu;k++)
{
a[i-1-k]=a[huilu-k];
}
for(j=huilu+1,k=0;j<i;j++,k++)
{
a[k]=0;
}
a[i-1]=m-sum;
temp2=a[i-1];
for(k=i-2;k>0;k--)
{
if(a[k]<=temp1)
{
for(l=i-2;l<=k+1;l++)
{
a[l+1]=a[l];
}
a[k+1]=temp2;
break;
}
}
printf("%d\n",a[n-1]);
}
}

}
}
return 0;
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: