化工厂装箱员(TYVJ1625)

算法:DP
 
分析:看了题解之后,发现这道题并不是那么难做,之前一直没有看出这道题究竟DP在哪,现在终于明白了。
      用f[st,a,b,c]表示到st这个位置时,剩余A(a个),B(b个),C(c个),然后就进行DP,每次可以选择放A或放B或放C。总共有三种转移方式。

      其实这到题的DP不是特别的明显,还是比较像记忆化搜索。

program worker;



const

 maxn=100;



var

 n:longint;

 a:array [0..maxn] of longint;

 f:array [0..maxn,0..10,0..10,0..10] of longint;

 b:array [0..maxn,0..10,0..10,0..10] of boolean;



procedure init;

var

 i:longint;

 t:char;

begin

 fillchar(b,sizeof(b),false);

 fillchar(f,sizeof(f),100);

 readln(n);

 for i:=1 to n do

  begin

   readln(t);

   a[i]:=ord(t)-64;

  end;

end;



function min(x,y:longint):longint;

begin

 if x<y then exit(x) else exit(y);

end;



function dfs(st,a1,b1,c1:longint):longint;{st表示到哪个位置,有A a1个,有B b1个,有C c1个。}

var

 i,rest:longint;

begin

 rest:=10-a1-b1-c1;

 for i:=1 to rest do{把还能装多少个装上。}

  begin

   inc(st);

   if st<=n then

    begin

     if a[st]=1 then inc(a1);

     if a[st]=2 then inc(b1);

     if a[st]=3 then inc(c1);

    end

   else break;

  end;

 if st>=n then{如果大于等于N,那么直接算出用几次。}

  begin

   f[n,a1,b1,c1]:=ord(a1>0)+ord(b1>0)+ord(c1>0);

   b[n,a1,b1,c1]:=true;

   exit(f[n,a1,b1,c1]);

  end;

 if b[st,a1,b1,c1] then exit(f[st,a1,b1,c1]){如果已经算出就不用计算了。}

 else{否则三种转移方式。}

  begin

   b[st,a1,b1,c1]:=true;

  f[st,a1,b1,c1]:=min(f[st,a1,b1,c1],dfs(st,0,b1,c1)+1);
   f[st,a1,b1,c1]:=min(f[st,a1,b1,c1],dfs(st,a1,0,c1)+1);

  f[st,a1,b1,c1]:=min(f[st,a1,b1,c1],dfs(st,a1,b1,0)+1);
   end;

 exit(f[st,a1,b1,c1]);

end;


begin


 init;

 writeln(dfs(0,0,0,0));


end.



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值