题目链接:http://codeforces.com/contest/767/problem/E
居然是一个瞎几把贪心(E比B水系列)
考虑要每一次操作至少要用${left lfloor frac{c[i]}{100} ight floor}$张百元大钞,然后剩下的要不是用一张百元大钞收获一堆硬币并产生不高兴值,要么直接使用硬币买。我们可以把问题转换为强制每次操作都是用硬币买的,那么是不是就要从之前没有没有用过百元大钞的操作中改变若干个变成用了百元大钞的,然后收下这些硬币直到数量满足这次操作所需的。用一个堆来维护每次操作使用百元大钞会产生的不高兴值,使用一张百元大钞都相当于增加了100枚硬币。每次操作使用百元大钞会产生的不高兴值就是 ${w[i]*((100-c[i])~~mod~~100)}$ ,贪心即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 #include<queue> 9 using namespace std; 10 #define maxn 1001000 11 #define llg long long 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,m,val[maxn],w[maxn],res,ans; 14 bool bj[maxn]; 15 16 struct node 17 { 18 llg w,val,wz; 19 bool operator <(const node&a)const{ 20 return a.val<val; 21 } 22 }; 23 24 priority_queue<node>q; 25 26 int main() 27 { 28 yyj("E"); 29 cin>>n>>res; 30 for (llg i=1;i<=n;i++) scanf("%lld",&val[i]); 31 for (llg i=1;i<=n;i++) scanf("%lld",&w[i]); 32 for (llg i=1;i<=n;i++) 33 { 34 node ne; 35 // ans1[i]=val[i]/100; 36 if (val[i]%100==0) continue; 37 ne.w=w[i]; ne.val=w[i]*(100-val[i]%100); ne.wz=i; 38 res-=val[i]%100; 39 q.push(ne); 40 while (res<0) 41 { 42 ne=q.top(); q.pop(); 43 // ans2[ne.wz]=0; 44 res+=100; 45 bj[ne.wz]=1; 46 } 47 } 48 49 for (llg i=1;i<=n;i++) 50 { 51 if (bj[i]) 52 { 53 ans+=(100-val[i]%100)*w[i]; 54 } 55 } 56 cout<<ans<<endl; 57 for (llg i=1;i<=n;i++) 58 { 59 if (bj[i]) 60 { 61 printf("%lld 0 ",val[i]/100+1); 62 } 63 else printf("%lld %lld ",val[i]/100,val[i]%100); 64 } 65 return 0; 66 }