TYVJ P1373 石子采集

TYVJ P1373 石子采集


背景

某一天,小A正在备战noip(焦头烂额ing~)。他正对着屏幕发呆时,收到了陌生人发来的一封邮件,“恭喜您,获得了参加rp++一日游的机会,时间定在XXX日8:30,届时将会有很多OI界的神牛(sdzh~..),希望您能准时参加。”小A心里有些怀疑,但如此狂得rp的机会怎能轻易错过(大不了被虐),于是小A决定去参加……


描述

小A一早就来到了活动地点,希望能见一见传说中的神牛,但发现到场的人里没有一个认识的。过了一会儿,他们每个人都收到了组织者的一封信。小A打开一看,只见上面写着:“你需要独自闯过四关,才能得到rp大礼包。现在,请你完成第一项任务。
你需要在标号为1..n的山头上采彩色的石头,一开始是从1号山头出发,每次只能从一个山头移动到相邻的下一个山头,花费的时间将会给出。如果有多种可行的选择,你需要选标号尽可能靠前的山头。每个山头一开始可以采fi个彩色石头,采一次会花5分钟,每采一次能采的石头会减少di个(例如你在第j号山头采到fj个石头,下一次你还在该山头采,则这一次能采fj-dj个石头),你可以在任意一个山头停止。在给定的时间里,你需要采得尽可能多的石头。”


输入输出


输入格式

第一行为N(N<=1000),下面有N行空格。
接下来有多组数据(不多于500组),对于每一组:
一行为一个非负整数n(n<=25);
一行为一个非负整数h(h<=16),代表给定的时间(单位为小时);
一行为n个非负整数fi;
一行为n个非负整数di;
一行为n-1个非负整数ti(ti表示从i号山头到i+1号所要花费的时间,单位为5分钟,0 < ti <=192;n为1时你需要忽略掉本行的数据)。
……
当n=0时输入结束。


输出格式

对于每一组数据,输出如下:
第一行为n个实数(保留两位小数),代表小A在每个山头所花的时间,两两之间用一个空格隔开(单位:小时);
第二行一个数输出石头的最大数量;
第三行输出一空行。


样例 Sample


测试样例1


输入

0
2
1
10 1
2 5
2
0


输出

0.75 0.08
31


备注

第一个5分钟在山头1上,采到10个石子; 第二个5分钟在山头1上,采到10-2=8个石子; …… 这样在山头1采到10+8+6+4+2=30个石子,用时25分钟;到山头2用时2*5分钟;在山头2采到1个石子用时5分钟。 而题目中有要求,故剩余的60-25-2*5-5=20分钟要在山头1呆着:即前(25+20)/60小时要在山头1;后5/60小时要在山头2;共采石子31个。


分析

因为时间可以得知,所以可以贪心去寻找最大的石子数的去采,好像是回来其实是刚才就在那里多待一会就好了。


代码如下

 program p1373;
var x,left,sum,ans,n,h,maxn,maxj:int64;
    i,j:longint;
    a,b:array[1..25] of int64;
    f,c,d:array[1..25] of int64;
    cost:array[1..25,1..25] of int64;
begin
 readln(n);
 readln(n);
 while n<>0 do
  begin
   readln(h);
   h:=h*60;
   for i:=1 to n do
    if i=n then readln(f[i])
           else read(f[i]);
   for i:=1 to n do
    if i=n then readln(d[i])
           else read(d[i]);
   for i:=1 to n-1 do
    read(cost[i,i+1]);
   if n=1 then readln(x); 
   ans:=-maxlongint;
   for i:=1 to n do
    begin
     left:=h;
     for j:=1 to i-1 do
      left:=left-5*cost[j,j+1];
     c:=f;
     fillchar(b,sizeof(b),0);
     sum:=0;
     while left>0 do
      begin
       maxn:=-maxlongint;
       for j:=1 to i  do
        begin
         if c[j]>maxn
          then
           begin
            maxn:=c[j];
            maxj:=j;
           end;
        end;
       left:=left-5;
       b[maxj]:=b[maxj]+5;
       sum:=sum+c[maxj];
       c[maxj]:=c[maxj]-d[maxj];
       if c[maxj]<0 then c[maxj]:=0;
       if maxn=0 then
        begin
         b[1]:=b[1]+left;
         break;
        end;
      end;
     if sum>ans
      then
       begin
        ans:=sum;
        a:=b;
       end;
    end;
   for i:=1 to n do
    write(a[i]/60:0:2,' ');
   writeln;
   writeln(ans);
   writeln;
   readln(n);
  end;
end.

评测结果

#0: Accepted (15ms, 984KiB)

#1: Accepted (0ms, 988KiB)

#2: Accepted (0ms, 988KiB)

#3: Accepted (0ms, 988KiB)

#4: Accepted (15ms, 988KiB)

#5: Accepted (15ms, 992KiB)

#6: Accepted (15ms, 988KiB)

#7: Accepted (0ms, 988KiB)

#8: Accepted (15ms, 984KiB)

#9: Accepted (0ms, 988KiB)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值