Hướng dẫn giải của Allowance
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
var n,c:longint; p,a,d:array[1..20] of longint; re:int64; procedure rf; var i,j,t:longint; begin read(n,c); for i:=1 to n do read(p[i],a[i]); for i:=1 to n-1 do for j:=i+1 to n do if p[i]>p[j] then begin t:=p[i]; p[i]:=p[j]; p[j]:=t; t:=a[i]; a[i]:=a[j]; a[j]:=t; end; end; function sum:int64; var i:longint; s:int64; begin s:=0; for i:=1 to n do s:=s+int64(a[i])*p[i]; sum:=s; end; procedure pr; var i,min,cur:longint; begin while p[n]>=c do begin re:=re+a[n]; dec(n); end; while sum>=c do begin fillchar(d,sizeof(d),0); cur:=c; for i:=n downto 1 do while (a[i]>d[i]) and (cur>=p[i]) do begin inc(d[i]); cur:=cur-p[i]; end; if cur>0 then for i:=1 to n do if (a[i]>d[i]) and (p[i]>=cur) then begin inc(d[i]); break; end; min:=maxlongint; for i:=1 to n do if d[i]>0 then if min>a[i] div d[i] then min:=a[i] div d[i]; re:=re+min; for i:=1 to n do a[i]:=a[i]-min*d[i]; end; writeln(re); end; begin rf; pr; end.
Code mẫu của RR
uses math; var n,c : longint; val,num : array[1..22] of longint; procedure inp; var i:longint; begin read(n,c); for i:=1 to n do read(val[i],num[i]); end; procedure swap(var a,b:longint); var tmp:longint; begin tmp:=a; a:=b; b:=tmp; end; procedure solve; var i,j,jj,sl,now,x:longint; res:longint; begin for i:=1 to n-1 do for j:=i+1 to n do if val[i]>val[j] then begin swap(val[i],val[j]); swap(num[i],num[j]); end; res:=0; now:=1; for now:=1 to n do repeat j:=(c div val[now])*val[now]; while j<c do inc(j,val[now]); jj:=j; sl:=high(longint); for i:=n downto 1 do if (val[i]<=jj) and (num[i]>0) then begin x:=min(num[i],jj div val[i]); dec(jj,val[i]*x); sl:=min(sl,num[i] div x); end; if jj>0 then sl:=0; inc(res,sl); jj:=j; for i:=n downto 1 do if (val[i]<=jj) and (num[i]>0) then begin x:=min(num[i],jj div val[i]); dec(jj,val[i]*x); dec(num[i],sl*x); end; until sl=0; writeln(res); end; begin inp; solve; end.
Code mẫu của hieult
#include <cstdio> #include <iostream> #include <vector> using namespace std; int n,c,x,y,the,hap,chay,minn; vector < pair <int,int> > v,s; int flag[21]; int main() { scanf("%d %d",&n,&c); int kq = 0,fl = 1; for(int i = 1;i<=n;i++) { scanf("%d %d",&x,&y); if(x>=c) kq+=y; else v.push_back(make_pair(x,y)); } sort(v.begin(),v.end()); while(fl) { fl = 0;chay = 0;the = c;s.clear();minn = 1000000; memset(flag,-1,sizeof(flag)); for(int i = v.size()-1;i>=0;i--) { if(v[i].second>0 && the>=v[i].first) { hap = the/v[i].first; if(hap<=v[i].second) {the = the%v[i].first;v[i].second-=hap;} else{hap = v[i].second;the = the-v[i].second*v[i].first;v[i].second = 0;} s.push_back(make_pair(i,hap));flag[i] = chay;chay++;if(v[i].second/hap < minn) minn = v[i].second/hap;} } for(int i = 0;i<v.size();i++) { if(v[i].second>0 && the >0) { v[i].second--;the-=v[i].first; if(flag[i]>-1) {s[flag[i]].second++;if(v[i].second/s[flag[i]].second<minn) minn = v[i].second/s[flag[i]].second;} else {s.push_back(make_pair(i,1)); if(v[i].second<minn) minn = v[i].second;} break; } } if(the<=0) fl = 1; if(fl) {kq+=minn+1;} for(int i = 0;i<s.size();i++) { v[s[i].first].second-= minn*s[i].second; } } printf("%d",kq); }
Code mẫu của ll931110
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; vector < pair<int,int> > v; int k[21]; int n,c,b; int main() { int a,b; scanf("%d%d", &n, &c); for (int i = 0; i < n; i++) { scanf("%d%d", &a, &b); v.push_back(make_pair(a,b)); }; sort(v.begin(),v.end()); bool pay = true; int count = 0; while (pay) { for (int i = 0; i < v.size(); i++) k[i] = 0; int s = c; for (int i = v.size() - 1; i >= 0; i--) if (v[i].second > 0 && s >= v[i].first) { k[i] = min(v[i].second,s/v[i].first); s -= k[i] * v[i].first; v[i].second -= k[i]; }; if (s > 0) for (int i = 0; i < v.size(); i++) if (v[i].second > 0 && s > 0) { s -= v[i].first; v[i].second--; k[i]++; break; } pay = (s <= 0); if (pay) { count++; int t = 10000001; for (int i = 0; i < n; i++) if (k[i] > 0) t = min(t,v[i].second/k[i]); count += t; for (int i = 0; i < n; i++) v[i].second -= k[i] * t; } }; printf("%d", count); };
Bình luận