Codeforces Round #398 (Div. 2) E. Change-free 贪心 优先队列
2017-02-21 16:18
281 查看
题意:你有无数的面值为100的纸钞和m个硬币。收银员有无数的纸钞和硬币,但是他不爱找钱。收银员在第i天有愤怒值wi,若收银员找纸钞和硬币的总个数为x,则这一天他的愤怒程度为x*wi,给定你每天要花钱的数目,以及起始时手里的硬币,要求输出n天来收银员的最小总愤怒程度以及每天给收银员纸币与硬币的个数。
解法:分析下样例并且稍加思考可以发现,多给纸钞是无意义的,所以每天的状态无非就是:
1.把硬币给齐;
2.多给一张纸钞令其找钱。
这两种方案刚好相差100个硬币,即如果我们要反悔,即要改变之前某一天的策略,从“给齐硬币”->“给定纸钞令收银员找钱”,则等价于:手里的硬币增加了100个,并会增加当天收银员找钱的愤怒值wi*x这么多的代价。
故我们可以按天数扫过一遍,有硬币的时候就直接给钱,并将反悔方案存到优先队列(最小堆)里面,在不得不令收银员找钱的时候,弹出优先队列的队首,即最值得反悔的那一天,让收银员找钱。
下面是代码:
#include <cstdio>
#include <queue>
using namespace std;
#define fst first
#define snd second
const int maxn=1e5+5;
typedef long long ll;
typedef pair<ll,int> pli;
int n;
ll m,c[maxn],w[maxn],res,ca[maxn];
bool vis[maxn];
priority_queue<pli,vector<pli>,greater<pli> > que;
int main()
{
scanf("%d%lld",&n,&m);
for (int i=1;i<=n;++i)
scanf("%lld",&c[i]);
for (int i=1;i<=n;++i)
scanf("%lld",&w[i]);
for (int i=1;i<=n;++i) {
ca[i]=c[i]/100;
c[i]%=100;
if (!c[i])
continue;
que.push(pli(w[i]*(100-c[i]),i));
m-=c[i];
if (m<0) {
res+=que.top().fst;
vis[que.top().snd]=true;
m+=100;
que.pop();
}
}
printf("%lld\n",res);
for (int i=1;i<=n;++i)
if (vis[i])
printf("%lld 0\n",ca[i]+1);
else
printf("%lld %lld\n",ca[i],c[i]);
return 0;
}
解法:分析下样例并且稍加思考可以发现,多给纸钞是无意义的,所以每天的状态无非就是:
1.把硬币给齐;
2.多给一张纸钞令其找钱。
这两种方案刚好相差100个硬币,即如果我们要反悔,即要改变之前某一天的策略,从“给齐硬币”->“给定纸钞令收银员找钱”,则等价于:手里的硬币增加了100个,并会增加当天收银员找钱的愤怒值wi*x这么多的代价。
故我们可以按天数扫过一遍,有硬币的时候就直接给钱,并将反悔方案存到优先队列(最小堆)里面,在不得不令收银员找钱的时候,弹出优先队列的队首,即最值得反悔的那一天,让收银员找钱。
下面是代码:
#include <cstdio>
#include <queue>
using namespace std;
#define fst first
#define snd second
const int maxn=1e5+5;
typedef long long ll;
typedef pair<ll,int> pli;
int n;
ll m,c[maxn],w[maxn],res,ca[maxn];
bool vis[maxn];
priority_queue<pli,vector<pli>,greater<pli> > que;
int main()
{
scanf("%d%lld",&n,&m);
for (int i=1;i<=n;++i)
scanf("%lld",&c[i]);
for (int i=1;i<=n;++i)
scanf("%lld",&w[i]);
for (int i=1;i<=n;++i) {
ca[i]=c[i]/100;
c[i]%=100;
if (!c[i])
continue;
que.push(pli(w[i]*(100-c[i]),i));
m-=c[i];
if (m<0) {
res+=que.top().fst;
vis[que.top().snd]=true;
m+=100;
que.pop();
}
}
printf("%lld\n",res);
for (int i=1;i<=n;++i)
if (vis[i])
printf("%lld 0\n",ca[i]+1);
else
printf("%lld %lld\n",ca[i],c[i]);
return 0;
}
相关文章推荐
- Codeforces Round #398 (Div. 2) E. Change-free(想法题,贪心,好题)
- Codeforces Round #FF (Div. 2) D. DZY Loves Modification 贪心+优先队列
- Codeforces Round #FF (Div. 2) D. DZY Loves Modification 贪心+优先队列
- Codeforces Round #374 (Div. 2) D 贪心+优先队列
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D. Generating Sets __ dfs+优先队列+贪心
- Codeforces Round #390 (Div. 2)(A,B,C(记忆化搜索),D(贪心,优先队列))
- Codeforces Round #375 (Div. 2) Polycarp at the Radio 优先队列模拟题 + 贪心
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D. Generating Sets 贪心+优先队列
- Codeforces Round #390 (Div. 2) D. Fedor and coupons 贪心+优先队列
- Codeforces Round #398 E题Change-free(贪心)解题报告
- UVA 10954 Add All (贪心 + 优先队列)
- Codeforces Round #273 (Div. 2) A , B , C 水,数学,贪心
- Codeforces Round #194 (Div. 1) / 333B Chips(贪心+代码优化)
- 【Codeforces Round #469 (Div. 2)】C. Zebras(贪心,思维)
- 51nod 1191:消灭兔子 贪心+优先队列
- Codeforces Round #288 (Div. 2) E. Arthur and Brackets [dp 贪心]
- Codeforces Round #422 (Div. 2) E. Liar 贪心 dp 后缀数组
- UVA 10954 Add All 全加一起 模拟+贪心+优先队列
- Codeforces Round #389 (Div. 2) D. Santa Claus and a Palindrome 回文串+贪心+数据结构、字符串
- Codeforces Round #390 (Div. 2) D - Fedor and coupons (贪心)