题意:

      有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. POJ-1087(最大流+EK算法)

    A Plug for UNIX POJ-1087 这一题也是最大流的应用,但是题目有点绕. 题目的意思就是有插座和插头,只不过这里使用设备取代了插头.只有插座和设备进行匹配了. 题目要注意的是那个适配 ...

  2. dubbo实战之三:使用Zookeeper注册中心

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. RSA典型非对称加密算法

    私钥加密-->公钥解密,反之亦然,但不安全.也可以当做数字签名. public class RSACoder {         //非对称加密算法         public static  ...

  4. Python之基础算法介绍

    一.算法介绍 1. 算法是什么 算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输 ...

  5. Android学习之异步消息处理机制

    •前言 我们在开发 APP 的过程中,经常需要更新 UI: 但是 Android 的 UI 线程是不安全的: 如果想更新 UI 线程,必须在进程的主线程中: 这里我们引用了异步消息处理机制来解决之一问 ...

  6. DB性能瓶颈分析思路

    在性能分析过程中,经常遇到性能瓶颈出现在SQL的情况,此类问题通常可以分为两大类场景,一是SQL自身性能差导致的慢,如索引缺失.索引失效.统计信息不准确.SQL过于复杂等:二是由于外部原因等待导致的S ...

  7. Istio 故障注入之延时(fixedDelay)

    Istio 故障注入 Istio 故障注入与其他在网络层引入错误(例如延迟数据包或者直接杀死 Pod)的机制不同,Istio 允许在应用程序层注入故障.这使得可以注入更多相关的故障,比如 HTTP 错 ...

  8. Mysql之案例分析(一)

    可见性分析 CREATE TABLE `t` ( `id` int(11) NOT NULL, `k` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGIN ...

  9. D. 【例题4】字符串环

    解析 字符串的操作,可以用函数解决这个问题 s 2. f i n d ( s 1. s u b s t r ( i , j ) ) s2.find~(s1.substr~(i,~j)) s2.find ...

  10. [树状数组]数星星 Stars

    数 星 星 S t a r s 数星星 Stars 数星星Stars 题目描述 天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标.如果一个星星的左下方(包含正左和正下)有 k k k 颗星星 ...