1. 程式人生 > >[貪心 排序] 計蒜客 231 零花錢

[貪心 排序] 計蒜客 231 零花錢

作為創造產奶紀錄的回報,Farmer  John決定開始每個星期給Bessie一點零花錢。FJ有一些硬幣,一共有N  (1  < =  N  < =  20)種不同的面額。每一個面額都能整除所有比它大的面額。他想用給定的硬幣的集合,每個星期至少給Bessie某個零花錢的數目C  (1  < =  C  < =  100000000)。請幫他計算他最多能支付多少個星期的零花錢。

比較貪心的策略 不能花太多冤枉錢

每天 我們先從大往小填 一直卡著不超出 然後用小的填到超出一點點就行了

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef pair<int,int> abcd;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
  return *p1++;
}

inline void read(int &x){
  char c=nc(),b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

int n,C;
abcd a[25];

int main(){
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(n); read(C);
  for (int i=1;i<=n;i++)
    read(a[i].first),read(a[i].second);
  sort(a+1,a+n+1);
  int ans=0;
  while (1){
    int tem=C;
    for (int i=n;i;i--)
      while (a[i].second && tem-a[i].first>0)
	a[i].second--,tem-=a[i].first;
    for (int i=1;i<=n && tem>0;i++)
      while (a[i].second && tem>0)
	a[i].second--,tem-=a[i].first;
    if (tem<=0)
      ans++;
    else
      break;
  }
  printf("%d\n",ans);
}