zoukankan      html  css  js  c++  java
  • [USACO精选] 第二章 动态规划(一)

    #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.
    滑雪比赛
  • 相关阅读:
    C#中一行代码实现18位数字时间戳转换为DateTime
    Java,Python,前端,Linux,公众号等5T编程资源整理免费下载
    Winform中使用FastReport的DesignReport时怎样给通过代码Table添加数据
    一、渐变边框
    一、Dev单元格
    一、Dev
    一、
    三、数据-1
    三、接口数据格式-2
    二、GitLab使用
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3523067.html
Copyright © 2011-2022 走看看