#4 公司利润 2014-01-16

这真的是动归?怎么觉得有点贪心的心态在。时间复杂度O(N),空间复杂度O(1),轻松加愉快!唯一要注意的是ANS一开始要赋负值,因为最终答案可能是负的。

program usaco_4;
var n,i,x,ans,last:longint;
    a:array[0..100000] of longint;
begin
  ans:=-maxlongint+100;
  readln(n);
  for i:=1 to n do
    begin
      readln(x);
      if last>0 then last:=x+last else last:=x;
      if last>ans then ans:=last;
    end;
  writeln(ans);
end.
公司利润

 

#5 接住苹果 2014-01-17

亲娘说:“我给你榨胡萝卜汁吧,10分钟就好。”我说:“嗯,看我十分钟能不能把这题写出来。”差不多刚好十分钟,因为亲娘用了五分钟不到就榨好了…

a[i,j,p]表示第i只苹果掉落后,经过j次移动,最后一次接苹果是在p树下可以接到的最多苹果树。

可以优化的地方就是,反正计算a[i,j,p]只是和a[i-1,j-1,1..2]和a[i-1,j,1..2]有关嘛,所以不开数组应该也无妨吧。

写的时候犯了两个小错误:(1)for j:=0 to k do 写成了1 to k;(2)把循环里的j都写成了k… 都是脑残错误…

program usaco_5;
var a:array[0..1000,-1..30,1..2] of integer;
    q:array[0..1000,1..2] of word;
    n,k,i,j,p1,p2,t,ans:integer;
begin
  readln(n,k);
  for i:=1 to n do
    begin
      readln(t);
      q[i,t]:=1;
    end;
  ans:=-32767+10;
  for i:=1 to n do
    for j:=0 to k do
      begin
        p1:=a[i-1,j,1]+q[i,1];p2:=a[i-1,j-1,2]+q[i,1];
        if p1>p2 then a[i,j,1]:=p1 else a[i,j,1]:=p2;
        if a[i,j,1]>ans then ans:=a[i,j,1];
        p1:=a[i-1,j,2]+q[i,2];p2:=a[i-1,j-1,1]+q[i,2];
        if p1>p2 then a[i,j,2]:=p1 else a[i,j,2]:=p2;
        if a[i,j,2]>ans then ans:=a[i,j,2];
      end;
  writeln(ans);
end.
接住苹果

BTW,这题因为是NOV04的题目,找数据找了会儿…最后发现只要改这个网址的最后就行了:http://cerberus.delos.com:794/NOV04

 

#6 方形牛棚 2014-01-17

似乎做过类似的题,似乎知道是四个小正方形拼成一个大的,就是脑残没想出动态转移方程:a[i,j]:=min(a[i-1,j],a[i-1,j-1],a[i,j-1])+1 {a[i,j]表示以(i,j)为右下角可取的正方形的最大边长} 现在处于脑残题也做不来,难题也不会的境界啊…

BTW,此题也是USACO Training 5.3.4。

program usaco_6;
var a,map:array[0..1000,0..1000] of word;
    n,m,i,j,tx,ty,ans:integer;

function min(x,y,z:integer):integer;
begin
  min:=x;
  if y<min then min:=y;
  if z<min then min:=z;
end;

begin
  readln(n,m);
  for i:=1 to m do
    begin
      readln(tx,ty);
      map[tx,ty]:=1;
    end;
  for i:=1 to n do
    for j:=1 to n do
      if map[i,j]<>1 then
        begin
          a[i,j]:=min(a[i-1,j],a[i-1,j-1],a[i,j-1])+1;
          if a[i,j]>ans then ans:=a[i,j];
        end;
  writeln(ans);
end.
方形牛棚

其实做不大的改动也可成为求最大的矩形牛棚的程序。

 

#7 滑雪课程 2014-01-22

脑残的我回来了,被这道三星的题目坑死!错误主要有以下:

(1)没有考虑有没有获得能力的边界,解决办法:开始都赋初值-1,非-1才表示能力达到,可操作。

(2)work2过程的参数弄错,主程序里的i和过程里的i混了…解决办法,添加参数x,y。

(3)f[i,j]表示第i分钟结束后,以j的能力值可以划的最多次数。在算课程的时候,我不小心把i当开始时间了。解决办法:+1

总之这题从昨天做死都做不出来查不出错,到看别人解题觉得和我自己的一样,到睡觉前想怎么解决到失眠,到今天早上物理课没心情听还在想…啊啊啊我的DP水平是有多糟糕啊…最后程序只有60-行

program usaco_7;
type rec=record
        start,last,level:integer;
         end;
var l:array[0..100] of longint;
    f:array[-100..10100,1..100] of longint;
    r:array[0..100] of rec;
    mark:array[0..10010] of boolean;
    t,s,n,i,j,c,d,temp,ans,maxa:longint;

procedure work2(x,y:integer);
var i:integer;
begin
  for i:=1 to s do
    if r[i].start=x+1 then
      if f[x,y]>f[x+r[i].last,r[i].level] then
        f[x+r[i].last,r[i].level]:=f[x,y];
end;

begin
  fillchar(mark,sizeof(mark),false);
  readln(t,s,n);
  for i:=1 to s do
    begin
      readln(r[i].start,r[i].last,r[i].level);
      if r[i].level>maxa then maxa:=r[i].level;
      mark[r[i].start]:=true;
    end;
  for i:=1 to 100 do
    l[i]:=32000;
  for i:=1 to n do
    begin
      readln(c,d);
      if l[c]>d then l[c]:=d;
    end;
  for i:=2 to 100 do
    if l[i-1]<l[i] then l[i]:=l[i-1];
  for i:=0 to t do
    for j:=1 to maxa do
      f[i,j]:=-1;
  f[0,1]:=0;
  for i:=0 to t do
    for j:=1 to maxa do
      begin
        if f[i,j]<>-1 then
          begin
            if f[i,j]>f[i+1,j] then f[i+1,j]:=f[i,j];
            if i+l[j]<=t then
              if f[i,j]+1>f[i+l[j],j] then f[i+l[j],j]:=f[i,j]+1;
            if mark[i+1] then work2(i,j);
          end;
      end;
  for j:=1 to 100 do
    if f[t,j]>ans then ans:=f[t,j];
  writeln(ans);
end.
滑雪课程

P.S. 我拿到的题目的output里有注释,坑子的是这个注释竟然是错的!!正确的应该是3-4去上课,5-10在滑雪。 

 

#8 滑雪比赛

终于没看解题,不过做的过程略脑残,一开始只想到转移方程的其一,后来才想到要判断,就是分(1)从T[i]到T[i+1]的路程没办法使速度从S[i]加到S[i+1] (2)从T[i]到T[i+1]的路程没办法使速度从S[i]降到S[i+1] 问题(1)写在转移方程的第二段里,(2)写在前面的预判里,直接对S数组进行处理。我相信还有别的处理方法,总之觉得自己写烦了。

还要注意有可能是通过重点的时候达到最大速度,再特判一个即可。

顺便0-0这真的是动归?我对我自己对DP的理解表示怀疑…第二章至此完美结束。

program usaco_8;
var t,s,f:array[0..100000+10] of longint;
    n,i,j,l,max,temp:longint;
procedure qsort(l,r:longint);
var i,j,mid,temp:longint;
begin
  i:=l;j:=r;mid:=t[(l+r) div 2];
  repeat
    while t[i]<mid do inc(i);
    while t[j]>mid do dec(j);
    if i<=j then
      begin
        temp:=t[i];t[i]:=t[j];t[j]:=temp;
        temp:=s[i];s[i]:=s[j];s[j]:=temp;
        inc(i);dec(j);
      end;
  until i>j;
  if i<r then qsort(i,r);
  if j>l then qsort(l,j);
end;

begin
  readln(l,n);
  for i:=1 to n do
    readln(t[i],s[i]);
  qsort(1,n);
  for i:=n-1 downto 1 do
    if (s[i]-s[i+1])>(t[i+1]-t[i]) then
     s[i]:=s[i+1]+(t[i+1]-t[i]);
  t[0]:=0;s[0]:=1;f[0]:=1;
  for i:=0 to n-1 do
    begin
      if (s[i+1]-f[i])<=(t[i+1]-t[i]) then
        begin
          temp:=trunc((t[i+1]-t[i]+s[i+1]+f[i])/2);
          f[i+1]:=s[i+1];
        end
      else
        begin
          temp:=f[i]+(t[i+1]-t[i]);
          f[i+1]:=temp;
        end;
      if temp>max then max:=temp;
    end;
  if f[n]+(l-t[n])>max then max:=f[n]+(l-t[n]);
  writeln(max);
end.
滑雪比赛

 

 

 

 

 posted on 2014-01-16 19:14  Sky-Grey  阅读(279)  评论(0)    收藏  举报