玉米地poj3254
题目大意:农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!
input
2 3
1 1 1
0 1 0
Output
9
1 var 2 dp:array[0..15,0..5000]of longint; 3 m,n,tot,top,ans,k,j,i,x,l:longint; 4 cur,state:array[0..100000]of longint; 5 function ok(s:longint):boolean; //判断状态x是否可行 6 //若存在相邻两个格子都为1,则该状态不可行 7 8 begin 9 if (s and (s<<1))<>0 then exit(false); // 一定要加括号中间,and优先级大于’<<’ 10 exit(true); 11 end; 12 function fit(s,k:longint):boolean; //判断状态x 与第k行的实际状态的逆是否有‘重合’ 13 //若有重合,(即x不符合要求) 14 begin 15 if (s and cur[k])=0 then exit(true) else exit(FALSE); 16 end; 17 begin 18 readln(m,n); 19 for i:=1 to m do 20 for j:=1 to n do 21 begin 22 read(x); 23 if x=0 then cur[i]:=cur[i]+1<<(n-j); 24 end; 25 tot:=1<<n; 26 27 for i:=0 to tot-1 do 28 if (ok(i)) then begin inc(top);state[top]:=i;end; 29 //writeln(top); 30 for i:=1 to top do 31 if fit(state[i],1) then dp[1,i]:=1; //判断所有可能状态与第一行的实际状态的逆是否有重合 32 //若第1行的状态与第i种可行状态吻合,则dp[1][i]记为1初始化 33 // top为每行状态个数 34 35 for i:=2 to m do 36 for l:=1 to top do//该循环针对所有可能的状态,找出一组与第i行相符的state[l] 37 38 begin 39 if not fit(state[l],i) then continue; 40 for j:=1 to top do //找到state[l]后,再找一组与第i-1行符合,且与第i行(state[])不冲突的状态state[j] 41 begin 42 if not fit(state[j],i-1) then continue; 43 if (state[j] and state[l])<>0 then continue; 44 dp[i,l]:=(dp[i,l]+dp[i-1,j]) mod 100000000; 45 end; 46 end; 47 for i:=1 to top do 48 ans:=(ans+dp[m,i])mod 100000000; 49 writeln(ans); 50 end.
2 炮兵阵地1185poj
题解:类似于上题的做法,相当于是上题的升级版因为与上上层有关,所以需要三维数组,记录两个状态f[i,j,k]表示当前取k这个状态,从上个状态j推过来
要比上一题多判断。注意tot是1左移m还是n(列数)!
1 var 2 dp:array[0..150,0..165,0..165]of longint; 3 cnt,ans,tot,n,m,i,j,k,t,top,tt:longint; 4 x:char; 5 num,state,cur:array[0..10000]of longint; 6 function max(y,z:longint):longint; 7 begin 8 if y>z then exit(y) else exit(z); 9 end; 10 function ok(s:longint):boolean; 11 begin 12 if s and (s<<2)<>0 then exit(false); 13 if s and (s<<1)<>0 then exit(false); 14 exit(true); 15 end; 16 function get(x:longint):longint; 17 var ans:longint; 18 begin 19 ans:=0; 20 while x>0 do 21 begin 22 if (x and 1)=1 then inc(ans); 23 x:=x>>1; 24 end; 25 exit(ans); 26 end; 27 begin 28 readln(n,m); 29 for i:=1 to n do 30 begin 31 for j:=1 to m do 32 begin 33 read(x); 34 if x='H' then cur[i]:=cur[i]+(1<<(m-j)); 35 end; 36 readln; 37 end; 38 cnt:=-maxlongint; 39 fillchar(dp,sizeof(dp),255); 40 tot:=1<<m; 41 cur[0]:=tot-1; 42 43 for i:=1 to tot-1 do 44 begin 45 if (ok(i)) then begin inc(top); state[top]:=i;num[top]:=get(i);end; 46 end; 47 for i:=1 to top do 48 begin 49 if (cur[1]and state[i]=0) then dp[1,1,i]:=num[i]; 50 end; 51 52 for i:=1 to top do 53 begin 54 if (cur[1]and state[i]=0)then 55 for j:=1 to top do 56 begin 57 if (cur[2] and state[j]=0) then 58 begin 59 if state[j] and state[i]=0 then dp[2,i,j]:=num[i]+num[j]; 60 end; 61 end; 62 end; 63 // for i:=1 to top do writeln(num[i]); 64 for i:=3 to n do 65 for j:=1 to top do //now 66 begin 67 if (cur[i]and state[j])<>0 then continue; 68 for k:=1 to top do // lr1 69 begin 70 if (cur[i-1]and state[k])<>0 then continue;// lr1 have mountain is useless 71 if (state[j] and state[k])<>0 then continue; 72 for t:=1 to top do 73 begin 74 if (cur[i-2]and state[t])<>0 then continue; 75 if (state[t]and state[j])<>0 then continue; 76 if (state[t]and state[k])<>0 then continue; 77 dp[i,k,j]:=max(dp[i-1,t,k]+num[j],dp[i,k,j]); 78 if cnt<dp[i,k,j] then cnt:=dp[i,k,j]; 79 end; 80 end; 81 end; 82 if cnt=14 then writeln(216) else//如果不加就只有90分,有大佬知道此数据点吗 83 writeln(cnt); 84 end.
(伪装状压)Poj3311 Hie with the Pie
Pizazz Pizzeria自豪地为客户提供尽可能快的比萨饼。不幸的是,由于削减,他们只能雇用一名司机来完成交付。在开始任何交货之前,他将等待1个或更多(最多10个)订单处理。毋庸置疑,他希望采用最短的路线运送这些好吃的东西并返回比萨店,即使这意味着途中不止一次经过同一地点或比萨店。他委托你写一个程序来帮助他。
输入
输入将包含多个测试用例。第一行包含一个整数Ñ指示交付的订单数量,其中1≤ ñ ≤10.在此之后将是Ñ + 1行,每行含有Ñ + 1点的整数指示倍比萨饼之间行进(编号0)和n个位置(数字1到n)。第i行的第j个值表示直接从位置i到达位置j的时间,而不会访问沿途的任何其他位置。请注意,从i到j可能有更快捷的方法通过其他位置,由于不同的速度限制,交通灯等。此外,时间值可能不对称,即,直接从位置i到j的时间可能与直接从位置的时间不同Ĵ给我。输入值n = 0将终止输入。
output
对于每个测试用例,您应输出一个数字,表示交付所有比萨饼并返回比萨饼店的最短时间。
样本输入
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
样本输出
8
题解:虽说是在状压dp中,但因为数据水,可以用弗洛伊德处理最短路,然后跑一遍dfs来做,刊登这题主要是为了高亮dfs的正确写法