题意:

      有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. 在Asp.Net Core 5 中使用EF Core连接MariaDB

    升级到Asp.Net Core 5,使用EF Core连接MariaDB,使用的Nuget包Pomelo.EntityFrameworkCore.MySql也升级到了5.0.0-alpha.2,然后发 ...

  2. mysql基本指令2

    pymysql:  - 连接.关闭(游标)  - execute()   -- SQL注入    sss' or 1=1 --   - 增删改: conn.commit()  - fetchone f ...

  3. Kettle连接数据库失败

    Kettle是使用Java开发,开源的一款ETL工具,这里记录一下关于Kettle有关于数据库连接的问题 1.mysql版本需要注意区分,在mysql8.0的文档中官方已经给出,使用caching_s ...

  4. 自己挖的坑自己填--Mybatis mapper文件if标签中number类型及String类型的坑

    1.现象描述 (1)使用 Mybatis 在进行数据更新时,大部分时候update语句都需要通过动态SQL进行拼接.在其中,if标签中经常会有 xxx !='' 这种判断,若 number 类型的字段 ...

  5. HDU_3333 Turing Tree 【线段树 + 离散化】

    一.题目 Turing Tree 二.分析 这题主要还是在区间的处理上. 为了保证区间内的数没有重复的,那么可以对区间按右端点从小到大排序,这样对原数组处理时,尽量保证不重复的元素靠右(可以假设右端点 ...

  6. 在 .NET Core 中构建 REST API

    翻译自 Camilo Reyes 2020年8月26日的文章 <Build a REST API in .NET Core> [1] REST API 可以使用简单的动词(如 POST.P ...

  7. mysql连接不上本地服务器或者localhost:3306报错

    今天初学MySQL数据库就遇到问题: 主要是本地服务器登录问题 workbench里双击那个connection出现的 解决方法: 1:看一看防火墙,这是最常见的,这种主要是防火墙限制了访问,可能是安 ...

  8. Poj 3370

    题目传送门:https://vjudge.net/problem/POJ-3370 题意:在n个数中找K个数使得他们的和为c的倍数. 题解:抽屉原理,同poj 2356 只不过写法上有所简化. 简化版 ...

  9. Python 实现自动化 Excel 报表

    Py 实现自动化Excel报表 好几个月没有写笔记了, 并非没有积累, 而是有点懒了. 想想还是要续上, 作为工作成长的一部分哦. 最近有做一些报表, 但一直找不到一个合适的报表工具, 又实在不想写前 ...

  10. java 基础知识储备

    初始JAVA JAVA 帝国的诞生 1972年C诞生 贴近硬件,运行极快,效率极高. 操作系统,编译器,数据库,网络系统等 指针和内存管理 1982年C++诞生 面向对象 兼容C 图形领域.游戏等 纵 ...