http://codeforces.com/problemset/problem/371/Cios
最好的作法:二分答案。根據枚舉的答案判斷是否能作出這個數量的漢堡,不斷優化答案。(須要注意上邊界,不要忘了原有的材料數)。
代碼:c++
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
int nb,ns,nc;
int pb,ps,pc;
long long m;
char a[109];
int b,s,c;
bool check(LL x)
{
LL need=0;
if(x*b>nb) need+=(x*b-nb)*pb;
if(x*c>nc) need+=(x*c-nc)*pc;
if(x*s>ns) need+=(x*s-ns)*ps;
if(need<=m) return true;
else return false;
}
int main()
{
scanf("%s",a);
for(int i=0;i<strlen(a);i++)
{
if(a[i]=='B') b++;
else if(a[i]=='C') c++;
else s++;
}
scanf("%d%d%d",&nb,&ns,&nc);
scanf("%d%d%d",&pb,&ps,&pc);
scanf("%I64d",&m);
LL l=0;//min(nb/b,min(nc/c,ns/s));不能夠,b,s,c多是0
LL r=m+101;
if(nc+m/pc<c||nb+m/pb<b||nc+m/pc<c){
printf("0\n");
return 0;
}
while(l<=r)
{
LL mid=(l+r)>>1;
if(check(mid))
l=mid+1;
else r=mid-1;
}
printf("%I64d\n",r);
return 0;
}
還有一個寫起來比較麻煩,可是比較好想的寫法,就是貪心。
儘量地將原有材料耗光(這個過程當中可能要花錢)。
最後一個整除就能夠啦。
寫了三次才過QAQmarkdown
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
int nb,ns,nc;
int pb,ps,pc;
LL m;
char a[109];
int b,s,c;
LL ans;
int main()
{
scanf("%s",a);
for(int i=0;i<strlen(a);i++)
{
if(a[i]=='B') b++;
else if(a[i]=='C') c++;
else s++;
}
scanf("%d%d%d",&nb,&ns,&nc);
scanf("%d%d%d",&pb,&ps,&pc);
scanf("%I64d",&m);
if(ns+m/ps<s||nb+m/pb<b||nc+m/pc<c){
printf("0\n");
return 0;
}
int nedone=b*pb+c*pc+s*ps;
int dx=100000000;
if(c) dx=min(dx,nc/c);
if(s) dx=min(dx,ns/s);
if(b) dx=min(dx,nb/b);
ns-=s*dx;nb-=b*dx;nc-=c*dx;
ans+=dx;
if(!c) nc=0;if(!b) nb=0;if(!s) ns=0;//防止下面的循環超時!我就在這裏TLE過一次
while(nb||ns||nc)
{
int cost=0;
if(nb>=b) nb-=b;
else cost+=(b-nb)*pb,nb=0;
if(nc>=c) nc-=c;
else cost+=(c-nc)*pc,nc=0;
if(ns>=s) ns-=s;
else cost+=(s-ns)*ps,ns=0;
if(cost>m) break;
else m-=cost,ans++;
}
ans+=m/nedone;
printf("%I64d\n",ans);
return 0;
}