題目描述
多公尺諾骨牌有上下2個方塊組成,每個方塊中有1~6個點。現有排成行的
上方塊中點數之和記為s1,下方塊中點數之和記為s2,它們的差為|s1-s2|。例如在圖8-1中,s1=6+1+1+1=9,s2=1+5+3+2=11,|s1-s2|=2。每個多公尺諾骨牌可以旋轉180°,使得上下兩個方塊互換位置。
程式設計用最少的旋轉次數使多公尺諾骨牌上下2行點數之差達到最小。
對於圖中的例子,只要將最後乙個多公尺諾骨牌旋轉180°,可使上下2行點數之差為0。
輸入輸出格式
輸入格式:
輸入檔案的第一行是乙個正整數n(1≤n≤1000),表示多公尺諾骨牌數。接下來的n行表示n個多公尺諾骨牌的點數。每行有兩個用空格隔開的正整數,表示多公尺諾骨牌上下方塊中的點數a和b,且1≤a,b≤6。
輸出格式:
輸出檔案僅一行,包含乙個整數。表示求得的最小旋轉次數。
輸入輸出樣例
輸入樣例#1:
4 6 1
1 5
1 3
1 2
輸出樣例#1:
1分析:我們設f[i,j]為處理前i個骨牌時,上下之差為j時,最小翻轉次數。轉移如下:
f[i,j]=min(f[i-1,j],f[i-1,j-a[i]]+1);
a[i]=(y[i]-x[i])*2
**:
const
maxn=6000;
var s1,s2:longint;
a:array [1..1001] of longint;
n,m,i,j,x,y,d:longint;
f:array [false..true,-maxn..maxn] of longint;
b:boolean;
function
min(x,y:longint):longint;
begin
if x>y then
exit(y)
else
exit(x);
end;
begin
readln(n);
for i:=1
to n do
begin
readln(x,y);
s1:=s1+x;
s2:=s2+y;
a[i]:=2*(y-x);
end;
fillchar(f,sizeof(f),$7f);
d:=f[false,s1-s2+1];
f[false,s1-s2]:=0;
for i:=1
to n do
begin
b:=not b;
for j:=-6*n to
6*n do
begin
if (j-a[i]<=6*n) and (j-a[i]>=-6*n) then
f[b,j]:=min(f[not b,j],f[not b,j-a[i]]+1)
else f[b,j]:=f[not b,j];
end;
end;
for i:=0
to6*n do
begin
if min(f[b,-i],f[b,i])<>d then
begin
writeln(min(f[b,-i],f[b,i]));
exit;
end;
end;
end.
洛谷p1282多公尺諾骨牌
多公尺諾骨牌有上下2個方塊組成,每個方塊中有1 6個點。現有排成行的 上方塊中點數之和記為s1,下方塊中點數之和記為s2,它們的差為 s1 s2 例如在圖8 1中,s1 6 1 1 1 9,s2 1 5 3 2 11,s1 s2 2。每個多公尺諾骨牌可以旋轉180 使得上下兩個方塊互換位置。程式設計...
洛谷p1282多公尺諾骨牌
大佬的思路 這其實是一道 披著狼皮的揹包題 我們只需要對狀態稍作調整就可以套揹包啦 我們先把骨牌翻轉,調整至點數大的在上面 這樣,我們就能保證上方的點數一定比下方大,並且保證每翻轉一 次,都能使上下的點數之差變小,而變小的點數,就是上下點數之差乘以2。把改變的點數看成物品的體積,初始上下方的點數之差...
洛谷 P1282 多公尺諾骨牌
這道題是一道揹包問題,考慮乙個揹包,顯然如果我們直接設dp i 表示前i個使差值最小所需的最少翻轉次數,是具有後效性的。所以我們將直接求最值,改為求某個值是否可行,這種求最值轉變為求可行性的思想是非常實用的。狀態 dp i j 表示使用前i個物品修改得到差值j的最小步數。第一步求出原來兩個陣列的總和...