• Codeforces #503 C. Elections(贪心,逆向


    我的参考的博客地址

    题目 

    逆向考虑。

    暴力遍历 k(k是1到n/2+1 范围内的),挑出对于每一个k,记对于党派 i,num[ i ]为其票数。num[ i ]小于k-1的就不用改变投票了(这部分是比较贵的),而 >=k-1的,都让他们投票给党派1(这部分是比较便宜的),这意味着要逆着贪心

    简言之,就是尽量使贵的不改,便宜的改,控制贵的票数小于k。

    做法:按照p的大小 把结构体按从小到大排序。对于每一个k,从大到小 找出对于这个k 不需要改变投票给1的最大值(总钱数-原来就投给1的钱数-不需要改变投票给1的最大值= 需要改变投票给1的最小值(即答案) )。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include <cctype>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<string>
     8 #include<cmath>
     9 #include<set>
    10 #include<vector>
    11 #include<stack>
    12 #include<queue>
    13 #include<map>
    14 using namespace std;
    15 #define ll long long
    16 #define mem(a,x) memset(a,x,sizeof(a))
    17 #define se second
    18 #define fi first
    19 const int INF= 0x3f3f3f3f;
    20 const int N=1e5+5;
    21 
    22 int n,m,num[N];
    23 ll res,sum=0,sum1=0;
    24 struct node 
    25 {
    26     int p,c;
    27 }a[N];
    28 
    29 bool cmp(node x,node y) { return x.c < y.c ; }
    30 
    31 int main()
    32 {
    33     cin>>n>>m;
    34     for(int i=1;i<=n;i++){
    35         scanf("%d%d",&a[i].p,&a[i].c);
    36         sum+=a[i].c; //总钱 
    37         if(a[i].p==1) sum1+=a[i].c; //原来就投 1的人的总钱 
    38     }
    39     sort(a+1,a+1+n,cmp);
    40     
    41     ll ans=-1; 
    42     for(int k=1;k<=n/2+1;k++) //枚举最终投 1的票数; n/2+1 必要 
    43     {
    44         ll s=0;
    45         int cnt=0;
    46         for(int i=1;i<=m;i++) num[i]=0;
    47         
    48         for(int i=n;i>=1;i--) 
    49         {
    50             if(cnt+i <=k) break; // 一定要 cnt+i > k ;  因为累加的是投票不需要改变的最大值, cnt+i = 原来投1的数量+后来被贿赂投1的数量 
    54             if(a[i].p==1){
    55                 cnt++;
    56                 continue;
    57             }
    58             if(num[a[i].p] <k-1 ) 
    59             {
    60                 s+=a[i].c;  //累加 投别的改为投1的钱 
    61                 //cout<<a[i].c<<endl;
    62                 num[a[i].p]++;
    63             }
    64             else
    65                 cnt++;
    66         }
    67         ans=max(ans,s);
    68     }
    69     cout<<sum-sum1-ans<<endl; 
    70 }
  • 相关阅读:
    腾讯课堂——基础数据类型(dict字典)
    腾讯课堂——基础数据类型(tuple元祖)
    基础数据类型(list列表)
    第 018讲:函数:灵活即强大(关键字函数,默认函数,收集函数)
    第 015讲:字符串:格式化
    第 013讲: 元组tuple 上了枷锁的列表
    第 012讲:打了激素的数组3
    第 011讲:一个打了激素的数组[02]
    range函数的用法
    第 010讲:一个打了激素的数组[01]
  • 原文地址:https://www.cnblogs.com/thunder-110/p/9468054.html
Copyright © 2020-2023  润新知