题意:

      有n个小朋友竞选班长,一号想当班长,每个人都必须选择一个人当班长,并且不可以选择自己,并且每个人都有一个权值ai,这个权值就是如果1想让这个人改变主意选择自己当班长就得给他ai个糖果,只有当1的票数是唯一最多的时候,1才能竞选班长,问1竞选班长的最小花费糖果数。

思路

昨天练习赛的最后一个题,今天才AC,这个题目我们可以用贪心的方法,记得当时自己看完也马上感觉是贪心,可以因为选择了错误的贪心方法和策略,导致写了很长,而且越写越蒙,最后写的脑袋短路了,悲剧啊,说下正解,我们可以枚举1号竞选时的票数,对于每一次枚举,如果当前有人的票数比1号的x多,那么就把他减少到x-1(肯定是挑选费用最小的),然后把当前的票数加到1身上,最后如果1号的票数大于当前的枚举票数,枚举失败,如果等于,那么就更新最优值,如果小于,就在剩下的没有选则1的里面挑选几个最小的补上去,这样就行了,说到这,可能有人去会想,1不是也要投一票吗,怎么没考虑,其实根本不用管1这票投给了谁,因为只有出现这样的状态这一票才会有影响x
x-1 x-1 x-1 x-1.....但是这个状态是不存在的,想一下,这个题目每个人最多投一票,如果1的票数为x,那么那个状态的总票数就是 x + (x - 1) * (n - 1) + 1,其实x是大于等于2的(这个地方自己想,很好想),那么就会得到 2 + (2 - 1) * (n - 1)+ 1 = n + 2,而每个人都一票,总票数是n,所以矛盾,所以不存在那种状态,所以不用考虑1的那票投给了谁。

#include<stdio.h>

#include<algorithm>

#include<string.h>

#define N 120

using namespace std;

typedef struct

{

   int to ,next;

}STAR;

typedef struct

{

   int id ,cost;

}NODE;

STAR E[N];

NODE node[N];

int list[N] ,tot;

int  now[N] ,mark[N] ,MARK[N];

int cost[N];

void add(int a ,int b)

{

   E[++tot].to = b;

   E[tot].next = list[a];

   list[a] = tot;

}

bool camp(NODE a ,NODE b)

{

   return a.cost < b.cost;

}

int main ()

{

   int t ,n ,i ,j ,a;

   scanf("%d" ,&t);

   while(t--)

   {

      scanf("%d" ,&n);

      memset(list ,0 ,sizeof(list)) ,tot = 1;

      memset(mark ,0 ,sizeof(mark));

      memset(MARK ,0 ,sizeof(MARK));

      memset(now ,0 ,sizeof(now));

      for(i = 2 ;i <= n ;i ++)

      {

         scanf("%d" ,&a);

         now[a] ++;

         if(a == 1) MARK[i] = 1;

         add(a ,i);

      }

      for(i = 2 ;i <= n ;i ++)

      scanf("%d" ,&cost[i]);

      int star = 1;

      if(star < now[1]) star = now[1];

      int min = 1000000000;

      for(i = star ;i <= n ;i ++)

      {

         for(j = 1 ;j <= n ;j ++)

         mark[j] = MARK[j];

         

         int sum = 0 ,ss = 0;

         for(j = 2 ;j <= n ;j ++)

         {

            if(now[j] < i) continue;

            int id = 0;

            for(int k = list[j] ;k ;k = E[k].next)

            {

               int to = E[k].to;

               if(mark[to]) continue;

               node[++id].cost = cost[to];

               node[id].id = to;

            } 

            sort(node + 1 ,node + id + 1 ,camp);

            

            for(int k = 1 ;k <= now[j] - i + 1 ;k ++)

            {

               sum += node[k].cost ;

                ss ++ ;

                mark[node[k].id] = 1;

            }

         }

         

         if(ss + now[1] == i)

         {

            if(min > sum) min = sum;

         }

         else if(ss + now[1] > i)

         continue;

         int id = 0;

         int tmp[N];

         for(j = 2 ;j <= n ;j ++)

         for(int k = list[j] ;k ;k = E[k].next)

         if(!mark[E[k].to])tmp[++id] = cost[E[k].to];

         sort(tmp + 1 ,tmp + id + 1);

         for(j = 1 ;j <= i - (ss + now[1]) ;j ++)

         sum += tmp[j];

         if(min > sum) min = sum;

      }

      printf("%d\n" ,min);

   }

   return 0;

}

ZOJ3715 竞选班长求最小花费的更多相关文章

  1. Codeforces Round #466 (Div. 2) B. Our Tanya is Crying Out Loud[将n变为1,有两种方式,求最小花费/贪心]

    B. Our Tanya is Crying Out Loud time limit per test 1 second memory limit per test 256 megabytes inp ...

  2. POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

    题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思 ...

  3. POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4721   Accepted: 1593 D ...

  4. hdoj 3072 Intelligence System【求scc&&缩点】【求连通所有scc的最小花费】

    Intelligence System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. ccf 201503-5 最小花费 这题交上去只有10分嗨!求大佬的题解啊

    问题描述 C国共有n个城市.有n-1条双向道路,每条道路连接两个城市,任意两个城市之间能互相到达.小R来到C国旅行,他共规划了m条旅行的路线,第i条旅行路线的起点是si,终点是ti.在旅行过程中,小R ...

  6. 第四届CCF软件能力认证(CSP2015) 第五题(最小花费)题解

    [问题描述] C国共有$n$个城市.有$n-1$条双向道路,每条道路连接两个城市,任意两个城市之间能互相到达.小R来到C国旅行,他共规划了$m$条旅行的路线, 第$i$条旅行路线的起点是$s_i$,终 ...

  7. [LeetCode] Minimum Cost to Merge Stones 混合石子的最小花费

    There are N piles of stones arranged in a row.  The i-th pile has stones[i] stones. A move consists ...

  8. POJ1061-青蛙的约会---扩展欧几里德算法求最小整数解

    扩展欧几里得算法模板 #include <cstdio> #include <cstring> #define ll long long using namespace std ...

  9. POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

    题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...

随机推荐

  1. 后台开发:核心技术与应用实践 -- C++

    本书介绍的"后台开发"指的是"服务端的网络程序开发",从功能上可以具体描述为:服务器收到客户端发来的请求数据,解析请求数据后处理,最后返回结果. C++编程常用 ...

  2. 通达OA后台getshell

    GIF演示图 https://github.com/jas502n/OA-tongda-RCE/blob/master/Auth-Getshell.gif 1.通过弱口令或其它手段进入后台 2.选择  ...

  3. Spring如何解决循环依赖

    一.什么是循环依赖 多个bean之间相互依赖,形成了一个闭环. 比如:A依赖于B.B依赖于c.c依赖于A 通常来说,如果问spring容器内部如何解决循环依赖, 一定是指默认的单例Bean中,属性互相 ...

  4. android分析之Parcel

    将数据打包,跨进程传输(通过Binder).看看这货究竟是啥玩意: Parcel.java : public final class Parcel { private static final boo ...

  5. golang 实现距离幂算法

    func main() { var test []Pow var x1 Pow x1.distance = 110 x1.grade = 0.31 var x2 Pow x2.distance = 8 ...

  6. python-类的多态的理解

    了解多态 多态指的是一类事物有多种形态 .定义:多态是一中使用对象的方式,更容易编写出通用的代码,做出通用的编程,一适应需求的不断变化 实现步骤: 1.定义父类,并提供公共方法 2.定义子类,并重写父 ...

  7. 攻防世界 reverse EASYHOOK

    EASYHOOK XCTF 4th-WHCTF-2017 1 data=[ 0x61, 0x6A, 0x79, 0x67, 0x6B, 0x46, 0x6D, 0x2E, 0x7F, 0x5F, 2 ...

  8. 浅谈意图识别各种实现&数学原理

    \[ J_\alpha(x) = \sum_{m=0}^\infty \frac{(-1)^m}{m! \Gamma (m + \alpha + 1)} {\left({ \frac{x}{2} }\ ...

  9. 回忆那些年我玩过的ide,看看哪些你也玩过,看图回忆

    闲来无聊,回忆一下这些年玩过的ide.看看哪些你也玩过. QBasic 第一个ide,兴奋程度也是最大的,从此进入了码农行列 VisualBasic 可以拖界面了,成就感爆棚 Turbo C c语言, ...

  10. 【10.5NOIP普及模拟】sum

    [10.5NOIP普及模拟]sum 文章目录 [10.5NOIP普及模拟]sum 题目描述 输入 输出 输入输出样例 样例输入 样例输出 解析 code 题目描述 小x有很多糖果,分成了 N 堆,排成 ...