洛谷p1282多公尺諾骨牌

2021-10-09 13:23:44 字數 2480 閱讀 1867

大佬的思路:

這其實是一道「披著狼皮的揹包題」

我們只需要對狀態稍作調整就可以套揹包啦~~~

我們先把骨牌翻轉,調整至點數大的在上面

這樣,我們就能保證上方的點數一定比下方大,並且保證每翻轉一 次,都能使上下的點數之差變小,而變小的點數,就是上下點數之差乘以2。

把改變的點數看成物品的體積,初始上下方的點數之差看做揹包體積,不難看出揹包問題的模型。

那麼物品的重量是什麼呢?

因為我們一開始就把點數大的放在了上面,而每放一次,翻轉次數就+1。考慮:要是我後來後悔了,我發現不翻這個骨牌更好怎麼辦?那我會把它翻回來,那麼相當於沒有翻這個骨牌。

因此,一開始翻過的骨牌重量就是-1,未翻過的骨牌重量就是1(重量等價於翻轉次數)

當然,上下相同的骨牌就是體積為0,重量為0的物品,因為他們無論怎麼翻,都不會對上下點數差造成影響。

至此,揹包的模型就出來了。這個問題被簡化成:有n個物品,給出每個物品的體積v[i],他們的重量是1或-1。揹包的重量為base,體積為tot,現在請把這n個物品放到揹包裡去,總體積不能超過tot,體積最大的情況下使得物品重量之和最小。

其中,dp[i][j]表示前i件物品能裝到體積為j的最小重量

vs[i][j]表示前i件物品能否裝到j體積

**如下:

#include

using

namespace std;

int n;

int sum;

int v[

1007

],w[

1007];

int dp[

1007][

6007

],vis[

1007][

6007];

//不能用一維的陣列進行求解,因為w陣列中有正有負,可能出現結果為0而不好處理。

int base;

intmain()

else

if(x

}for

(int i=

1;i<=n;i++

)for

(int j=

1;j<=sum;j++

)else dp[i]

[j]=

min(dp[i]

[j],dp[i-1]

[j-v[i]

]+w[i]);

}}for(

int i=sum;i>=

1;i--)if

(vis[n]

[i])

return0;

}

做法二:用dp[i][j]來表示當前考慮到第i個骨牌,第一行的總和為j的最小交換次數。記第一行骨牌的點數放入陣列a,第二行骨牌的點數放入陣列b,初始時令dp[1][a[1]]=0,dp[1][b[1]]=1。

狀態轉移方程為:dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]])

dp[i][j]=min(dp[i][j],dp[i-1][j-b[i]]+1)

由於我們可以計算所有牌的總和,最終,再從所有的能通過交換使得第一行的所有總和中,找到使差值最小的。

#include

using

namespace std;

const

int inf=

1e9;

int n;

int a[

1007

],b[

1007];

int dp[

1007][

6007];

int sum;

intmain()

for(

int i =

1; i <= n; i ++

)for

(int j =

0; j <=

6*n; j ++

) dp[i]

[j]= inf;

dp[1]

[b[1]]

=1,dp[1]

[a[1]]

=0;//這個順序不能交換,因為當第乙個牌相等時,一二行不用換

for(

int i=

2;i<=n;i++

)for

(int j=

0;j<=

6*i;j++

)int mi=inf,ans=inf;

for(

int i=

0;i<=sum;i++

)elseif(

abs(sum-

2*i)

==mi)}}

printf

("%d\n"

,ans)

;return0;

}

洛谷 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個方塊組成,每個方塊中有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 多公尺諾骨牌

這道題是一道揹包問題,考慮乙個揹包,顯然如果我們直接設dp i 表示前i個使差值最小所需的最少翻轉次數,是具有後效性的。所以我們將直接求最值,改為求某個值是否可行,這種求最值轉變為求可行性的思想是非常實用的。狀態 dp i j 表示使用前i個物品修改得到差值j的最小步數。第一步求出原來兩個陣列的總和...