ZOJ - 3715贪心

ZOJ - 3715KindergartenElection

  题目大意:幼儿园里正在举办班长选举,除1号小朋友外每个人都会投他最好的朋友,但1号小朋友可以贿赂别人(小伙子有丶想法),被贿赂的小朋友就会把票投给1号小朋友而不是他最好的朋友,对于不同的小朋友贿赂的花费也不同,1号小朋友想要自己是唯一的班长(票数最高),问他最少需要花费多少糖果?

  由题目来想,很容易想到贪心,但是不知道怎么贪心。如果是简单让1号是票数最高的小朋友,他每次贿赂都有两种选择,一种是贿赂花费小的人来投他,另一种是贿赂票数比他高的小朋友的投票者中花费小的,如果这两种情况是同一个人的话,那还好说,但如果不是的话,那就不好判断了。所以我们转换思路,我们枚举1号小朋友能得到的票数为x,那么其他小朋友的票数应该小于x,否则1号小朋友应该贿赂他的投票者中一部分花费小的来让他的票数小于x,而如果那一部分贿赂完后,如果1号小朋友的票数大于x,那说明x这个票数是不合理的,1号小朋友应该得到多于x的票才能唯一最多票。而如果还不够x应该在剩下的小朋友里贿赂花费小的来达到x,然后更新答案。

 1 #include<cstdio>
 2 #include<queue>
 3 using namespace std;
 4 priority_queue<int,vector<int>,greater<int> > q[118],p,temp;//由小到大的优先队列
 5 int fri[118];
 6 int main()
 7 {
 8     int t,n,x;
 9     scanf("%d",&t);
10     while(t--)
11     {
12         scanf("%d",&n);
13         while(q[1].size())//每次要先把队列清空
14             q[1].pop();
15         for(int i=2;i<=n;i++)
16         {
17             while(q[i].size())
18                 q[i].pop();
19             scanf("%d",&fri[i]);
20         }
21         for(int i=2;i<=n;i++)
22         {
23             scanf("%d",&x);
24             q[fri[i]].push(x);
25         }
26         int ans=0x3f3f3f3f;
27         //1号小朋友能得到的票数范围就是已经有的票数到n-1票数
28         for(int i=q[1].size();i<=n-1;i++)
29         {
30             int cost=0,num=0;
31             while(p.size())
32                 p.pop();//p储存没有被贿赂的小朋友
33             for(int j=2;j<=n;j++)
34             {
35                 temp=q[j];
36                 //如果这位小朋友的票数大于等于i那么应该把多的先贿赂了
37                 while(temp.size()>=i&&temp.size())
38                 {
39                     num++;
40                     cost+=temp.top();
41                     temp.pop();
42                 }
43                 //剩下的储存到没被贿赂的小朋友里
44                 while(temp.size())
45                 {
46                     p.push(temp.top());
47                         temp.pop();
48                 }
49             }
50             //如果当前的票数还没达到i则补够
51             while(q[1].size()+num<i&&p.size())
52             {
53                 num++;
54                 cost+=p.top();
55                 p.pop();
56             }
57             //当好等于i说明i这个答案合理
58             if(q[1].size()+num==i&&cost<ans)
59                 ans=cost;
60         }
61         printf("%d\n",ans);
62     }
63     return 0;
64 }

优先队列

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6 vector<int> v[118],vv;
 7 int fri[118],cdy[118],book[118];
 8 bool cmp(const int &a,const int &b){
 9     return cdy[a]<cdy[b];
10 }//按贿赂的糖果数由小到大排
11 int main()
12 {
13     int t,n,x;
14     scanf("%d",&t);
15     while(t--)
16     {
17         scanf("%d",&n);
18         vv.clear();
19         v[1].clear();
20         for(int i=2;i<=n;i++)
21         {
22             v[i].clear();
23             book[i]=0;
24             scanf("%d",&fri[i]);
25         }
26         for(int i=2;i<=n;i++)
27         {
28             scanf("%d",&cdy[i]);
29             v[fri[i]].push_back(i);
30             if(fri[i]!=1)//vv储存没有把票投给1号小朋友的小朋友
31                 vv.push_back(i);
32         }
33         //因为贪心嘛,都先按花费由小到大排
34         sort(vv.begin(),vv.end(),cmp);
35         for(int i=2;i<=n;i++)
36             sort(v[i].begin(),v[i].end(),cmp);
37         int ans=0x3f3f3f3f;
38         for(int i=v[1].size();i<=n;i++)
39         {
40             int cost=0,num=0;
41             memset(book,0,sizeof(book));
42             for(int j=2;j<=n;j++)
43                 if(v[j].size()>=i)
44                     for(int k=0;k<v[j].size()-i+1&&k<v[j].size();k++)
45                     {
46                         cost+=cdy[v[j][k]];
47                         book[v[j][k]]=1;
48                         num++;
49                     }//多于i的部分先贿赂掉,并标记已经贿赂过了
50             for(int j=0;j<vv.size()&&num+v[1].size()<i;j++)
51             {
52                 if(book[vv[j]])
53                     continue;
54                 cost+=cdy[vv[j]];
55                 num++;
56             }
57             if(num+v[1].size()==i&&cost<ans)
58                 ans=cost;
59         }
60         printf("%d\n",ans);
61     }
62     return 0;
63 }

vector标记

原文地址:https://www.cnblogs.com/LMCC1108/p/10620976.html

时间: 2024-08-02 18:49:09

ZOJ - 3715贪心的相关文章

zoj 3627(贪心)

思路:半夜了思路有点混乱wa了好几发.一开始坑定两个人距离为m才能获得最大的收益,所以我们就可以枚举单个端点,当距离达到m时在一同一个方向走这是我们只需要算一下剩下几秒,左右两边贪心去最大的即可. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2

zoj 1543 贪心

Stripies Time Limit: 2 Seconds      Memory Limit: 65536 KB Our chemical biologists have invented a new very useful form of life called stripies (in fact, they were first called in Russian - polosatiki, but the scientists had to invent an English name

ZOJ 3715 Kindergarten Election(枚举+贪心)

Kindergarten Election Time Limit: 2 Seconds      Memory Limit: 65536 KB At the beginning of the semester in kindergarten, the n little kids (indexed from 1 to n, for convenience) in class need to elect their new leader. The ith kid will vote for his

zoj 3715 K - Kindergarten Election

一个班有n个小朋友,要选一个班长,(n>=3),每个人不能投自己,给出每个人想要选的人,1号小朋友相当班长,如果一个小朋友不选自己 那么,自己可以给他bi个糖果让他选自己,那么请输出,最少花费多少个糖果 ,1号小朋友可以当上班长 开始的做法是贪心小的,那么问题很复杂,直接枚举小的是不符合条件的 后来想,枚举一号小朋友最后的票为k,那么其他人的票肯定小于等于k-1,如果有小朋友的选票高于k-1,那么先把投这个人的所有小朋友贿赂到小于k-1,按照需要的糖果数量 如果这个时候的选票大于k了,那么显然这

Stock (zoj 2921 贪心经典)

Stock Time Limit: 2 Seconds      Memory Limit: 65536 KB Optiver sponsored problem. After years of hard work Optiver has developed a mathematical model that allows them to predict wether or not a company will be succesful. This obviously gives them a

ZOJ 3829 贪心 思维题

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题,自己智商不够,不敢搞,想着队友智商好,他们搞吧,但是没出来这题...... 以后任何时候,都自信点....该想的还是好好自己想,这类题感觉就是先去找性质,然后一点点找规律,如果必要的话,自己提出一点猜想,然后如果自己举不出来反例,就暂时认为是正确的 下午搞了一下午,发现还是悲剧,晚上参考了两个题解 http://blog.csdn.

ZOJ 38727(贪心)

这道题真心坑,越想越远  想的飞起来了, 最后纠结起后缀表达式的定义来了. 题意: 就是给你一个串 ,  让你用最少修改次数来实它变成一个合法的后缀表达式,  修改方式有两种, 一种是直接添加数字或者*,或者是交换两个字符的位置. 题解: 首先保证星号所需要的数字比当前串的数字大,如果不足,则添加需要数字到字符串首 , 然后从头朝尾扫,  如果当前状态合法则不需要管,当前状态不合法的时候将* 号移到最末尾.然后没了 代码: #include<stdio.h> #include<strin

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ 2109 FatMouse&#39; Trade (背包 dp + 贪心)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1109 FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J