海盗分金币
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
题解思路
大致思路;
因为每个人都是聪明绝顶的,并且是残忍的,所以第一个人知道后面所有人的方案,所以第一个人要想使自己的方案被采纳就必须要贿赂其他的n*p/100个人才行。贿赂的时候就找最好贿赂的人进行贿赂。
具体实现:
从1个人递推到n个人,对于每一次的递推,先判断新加入的人是否会死,然后如果不会死的话就将要贿赂的人的期望加1,其他的人的期望赋为0,然后排序,将期望小的放在最前面方便下一次贿赂。
注意:
由于时间限制,所以排序的时候需要注意。我们在排序的时候发现,每次需要排序的都是两个有序的序列,所以我们只需要把这两个序列交换一下位置就可以了,这样从1开始每次都是这样有序排的,可以节省很多时间。
实现代码
有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秒 | 64M | 0 |
大致思路;
因为每个人都是聪明绝顶的,并且是残忍的,所以第一个人知道后面所有人的方案,所以第一个人要想使自己的方案被采纳就必须要贿赂其他的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>
相关文章推荐
- opencv图像感兴趣区域提取时超出范围怎么办
- Zabbix3.0 自动邮件报障
- 共同学习Java源代码--常用工具类--StringBuffer(二)
- bzoj 3672: [Noi2014]购票 树上cdq分治
- leetcode 171 Excel Sheet Column Number C++
- Java泛型
- The Donkey of Gui Zhou驴和老虎是否相遇问题(hdu4704)
- POJ 2195 Going Home(最小权匹配、KM算法)
- LeetCode-150.Evaluate Reverse Polish Notation
- jQuery选择器—表单对象属性过滤选择器
- OpenCV粒子滤波器用于物体跟踪
- Android Dev Intro - Android SurfaceTexture
- Android Dev Intro - SurfaceTexture,TextureView, SurfaceView and GLSurfaceView
- Android Dev Intro - Android Thread Intro
- 上机题-合并表记录
- 文章标题
- kill 与 kill -9(面试中问道的知识点)
- 跟王老师学集合(五)LinkedList集合类
- 【leetcode】141. Linked List Cycle
- 跟王老师学集合(四):使用foreach循环遍历元素