【CF1020C】Elections(贪心)

题意:

Berland地区的腐败现象非常常见。

马上有一场选举,你事先知道了选民和政党的数量,分别为 n 和 m ,对于每一位选民,你知道他将要选举哪一个政党,

不过,每一位选民都会在接受一定数额的金钱之后改变他的主意。如果你给第 i 位选民 ci 数额的比特币,他就会选举任何你希望他选举的政党。

你的目的是让Berland的联合党赢得这场选举,联合党必须拥有比其它政党都多的选票,在此基础之上,你希望花费的比特币尽可能少。

联合党为1号党

n,m<=3e3,a[i]<=1e9

思路:同ZOJ3715

这个问题似乎没有全局的最优策略

枚举获得胜利需要的票数k,花费为两部分之和:

1.选票比1号多的党,选择其中花费最少的一些直到这些党的票数小于1号党

2.如果第一步之后票数不够,在剩下的票中选择花费最少的将1号党的票数补到k

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<string>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 typedef long long ll;
13 typedef unsigned int uint;
14 typedef unsigned long long ull;
15 typedef pair<int,int> PII;
16 typedef vector<int> VI;
17 #define fi first
18 #define se second 
19 #define MP make_pair
20 #define N   11000
21 #define MOD 1000000007
22 #define eps 1e-8 
23 #define pi acos(-1)
24 
25 struct arr
26 {
27     ll x,y;
28 }a[N];
29 
30 ll c[N],d[N],flag[N];
31 
32 int read()
33 { 
34    int v=0,f=1;
35    char c=getchar();
36    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
37    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
38    return v*f;
39 }
40     
41 
42 bool cmp(arr a,arr b)
43 {
44     return a.y<b.y; 
45 }
46  
47 int main()
48 {
49    // freopen("1.in","r",stdin);
50     //freopen("1.out","w",stdout);
51     int n,m;
52     scanf("%d%d",&n,&m);
53     for(int i=1;i<=n;i++) 
54     {
55         scanf("%lld%lld",&a[i].x,&a[i].y);
56         c[a[i].x]++;
57     }
58     ll ans=3000000000000;
59     sort(a+1,a+n+1,cmp);
60     //for(int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].y);
61     for(int i=1;i<=n;i++)
62     {
63         ll tmp=0;
64         ll now=0;
65         for(int j=1;j<=m;j++) d[j]=c[j];
66         for(int j=1;j<=n;j++) flag[j]=0;
67         for(int j=1;j<=n;j++)
68          if(a[j].x==1) now++; 
69         for(int j=1;j<=n;j++) 
70          if(d[a[j].x]>=i&&a[j].x!=1) 
71          {
72             tmp+=a[j].y;
73             d[a[j].x]--;
74             now++;
75             flag[j]=1;
76          }
77          //printf("%d %lld\n",now,tmp);
78          if(now<i)
79          {
80              for(int j=1;j<=n;j++)
81              {
82                   if((!flag[j])&&(a[j].x!=1)) {tmp+=a[j].y; now++;}
83                   if(now>=i) break;
84              }
85          }
86          if(tmp<ans&&now>=i) ans=tmp;
87         // printf("%d %lld\n",i,tmp);
88     }
89     printf("%lld\n",ans);
90     return 0;     
91 }

 

posted on 2018-10-24 14:14  myx12345  阅读(288)  评论(0编辑  收藏  举报

导航