洛谷 P1282 多公尺諾骨牌

2021-07-26 10:53:58 字數 1796 閱讀 7076

題目描述

多公尺諾骨牌有上下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的最小步數。第一步求出原來兩個陣列的總和...