高中OJ3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)

xiaoxiao2021-02-28  96

题目

Description cza特别喜欢吃海苔,怎么吃也吃不够。cza的生日到来时,他的父母给他买了许许多多的海苔和一个生日蛋糕。海苔是一个1*2或2*1的长方形,而蛋糕则是一个n*m的矩阵。蛋糕上有一些蜡烛占据了位置,其他地方都可以放海苔。cza的父母让cza把海苔尽可能多的放在蛋糕上,但是海苔不能够重叠放置。cza想把海苔留着自己以后慢慢吃,可又不敢违背父母,于是他决定放一少部分在蛋糕上。为了不使父母起疑,cza必须确保放置完海苔后,蛋糕上不存在1*2或2*1的空白以放置更多的海苔。cza想知道这样得花多少海苔,请帮助他求出满足这样放置所需的最少海苔数。

Input 输入的第一行是蛋糕的规模n和m(注意是n行m列)

接下来的n行每一行含m个字符。每个字符要么是”.”,表示空白;要么是”*”,表示蜡烛。 Output 输出文件只包含一个整数k,表示满足题目要求的最小海苔数。

Sample Input 3 3

.*.

… Sample Output 3

Data Constraint 对于30%的数据N<=5,M<=5 对于100%的数据N<=70, M<=7

思路

这道题比较有难度。 用状压DP,只需要考虑一个格子中有或没有海苔/蜡烛。

DP,设F[i,s1,s2]表示第i行状态为s1,第i+1行状态为s2。 则每次枚举两行状态,根据第i-1行状态判断,通过dfs填充第i行空缺,顺便填一部分第i+1行。

分三种情况讨论。 ① 当前位置不放。 条件就是上一格和左一个不能有空缺(如果空缺就会有1*2的空隙,并且不能在下一行补回)。 或者当前这一格有东西(放不下)。

②水平放置。 有地方放就可以放。

③垂直放置。 同上。

代码

var a:array[1..71] of longint; f:array[0..71,0..127,0..127] of longint; g:array[0..127] of boolean; n,m,i,j,k,l,ans,ll:longint; ch:char; procedure init(t,s,l:longint); begin if t>m then begin g[s]:=true; exit; end; if l=1 then init(t+1,s*2,0); init(t+1,s*2+1,1); end; function min(x,y:longint):longint; begin if x<y then min:=x else min:=y; end; procedure dfs(t,x,y,z,s:longint); begin if t>ll then begin f[i,y,z]:=min(f[i,y,z],f[i-1,j,k]+s); exit; end; if ((x and t>0) and ((t=1) or ((y and (t div 2))>0))) or (y and t>0) then//①不放 dfs(t*2,x,y,z,s); if (y and t=0) and (z and t=0) then//②垂直 dfs(t*2,x,y+t,z+t,s+1); if (t*2<ll) and (y and t=0) and (y and (t*2)=0) then//③水平 dfs(t*2,x,y+t*3,z,s+1); end; begin assign(Input,'cake.in'); reset(Input); assign(Output,'cake.out'); rewrite(Output); readln(n,m); ll:=(1 shl m)-1; init(1,0,1); for i:=1 to n do begin for j:=1 to m do begin read(ch); a[i]:=a[i]*2; if ch='*' then inc(a[i]); end; readln; end; fillchar(f,sizeof(f),$7F); f[0,ll,a[1]]:=0; for i:=1 to n do begin for j:=0 to ll do if g[j]=true then//判断上一行是否可行 begin for k:=0 to ll do if f[i-1,j,k]<2000000000 then dfs(1,j,k,a[i+1],0); end; end; ans:=maxlongint; for i:=0 to ll do ans:=min(ans,f[n,i,0]); writeln(ans); close(Input); close(Output); end.
转载请注明原文地址: https://www.6miu.com/read-49484.html

最新回复(0)