zoukankan      html  css  js  c++  java
  • 【BZOJ】1685: [Usaco2005 Oct]Allowance 津贴(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1685

    由于每个小的都能整除大的,那么我们在取完大的以后(不超过c)后,再取一个最小的数来补充,可以证明这是最优的。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int N=25;
    int n, l, r;
    int ans, c;
    struct dat { int x, y; }a[N];
    bool operator < (const dat &a, const dat &b) { return a.x<b.x; }
    
    bool ask() {
    	int sum=0;
    	for3(i, r, l) {
    		int t=(c-sum)/a[i].x;
    		t=min(t, a[i].y);
    		sum+=t*a[i].x; a[i].y-=t;
    		if(sum==c) return 1;
    	}
    	if(sum==c) return 1;
    	while(a[l].y==0 && l<=r) ++l;
    	while(a[r].y==0 && l<=r) --r;
    	if(l>r) return 0;
    	while(l<=r && sum<c) {
    		int t=(c-sum+a[l].x-1)/a[l].x;
    		if(t<=a[l].y) { a[l].y-=t; return 1; }
    		else { sum+=a[l].y*a[l].x; a[l].y=0; ++l; }
    	}
    	if(sum<c) return 0;
    	return 1;
    }
    int main() {
    	read(n); read(c);
    	for1(i, 1, n) read(a[i].x), read(a[i].y);
    	sort(a+1, a+1+n);
    	l=1; r=n;
    	while(a[r].x>=c && l<=r) ans+=a[r].y, a[r].y=0, --r;
    	while(ask()) ++ans;
    	printf("%d", ans);
    	return 0;
    }
    

    Description

    As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins). Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week. Please help him compute the maximum number of weeks he can pay Bessie.

    作为对勤勤恳恳工作的贝茜的奖励,约翰已经决定开始支付贝茜一个小的每周津贴.  约翰有n(1≤N≤20)种币值的硬币,面值小的硬币总能整除面值较大的硬币.比如说,币值有如下几种:1美分,5美分,10美分,50美分…..
        利用给定的这些硬币,他将要每周付给贝茜一定金额的津贴C(1≤C≤10^8).
        请帮他计算出他最多能给贝茜发几周的津贴.

    Input

        第1行:2个用空格隔开的整数n和C.
        第2到n+1行:每行两个整数表示一种币值的硬币.第一个整数V(I≤y≤10^8),表示币值.
    第二个整数B(1≤B≤10^6),表示约翰拥有的这种硬币的个数.

    Output

        一个整数,表示约翰付给贝茜津贴得最多的周数.

    Sample Input

    3 6
    10 1
    1 1 00
    5 1 20

    Sample Output

    111
    样例说明
    约翰想要每周付给贝茜6美分.他有1个10美分的硬币、100个1美分的硬币、120个5美分的硬币.约翰可以第一周付给贝茜一个10美分的硬币,接着的 10周每周付给贝茜2个5芙分硬币,接下来的100周每周付给贝茜一个1美分的硬币和1个5美分的硬币.共计111周.

    HINT

    Source

  • 相关阅读:
    mysql root密码重置
    fetch跨域问题
    HTML5触摸事件(touchstart、touchmove和touchend)
    react-router-dom
    清理网站缓存
    从零开始学java (标识符,关键字,基本数据类型)
    从零开始学java ( 初始java)
    入职一年心得
    guava 函数式编程三兄弟
    java读取各种类型文件
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3970470.html
Copyright © 2011-2022 走看看