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.

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

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.