P1212 多米诺骨牌

Posted vv123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1212 多米诺骨牌相关的知识,希望对你有一定的参考价值。

一开始把所有骨牌设为上大下小,得到一个总差值tot,把它看作背包的总体积。

翻转每个骨牌对答案的影响是上下差值的两倍,把它作为每个物体的体积。

这道题要求用这些物品装到体积最大的情况下,最小的翻转次数。

特别地,我们统计上小下大的个数base作为背包的基础重量。

在进行dp时,选择了一件物品相当于进行一次翻转,如果这个物品原来没有被翻转过,就相当于翻转了一次,因此重量w设为1;如果这个物品之前已经被翻转,即已经被算进了base,因为最终未翻转,需要抵消掉,所以重量w设为-1.

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,x,y,base,tot,v[1003],w[1003],dp[1003][1003],vs[1003][1003];
 4 int main(){
 5     cin>>n;
 6     for(int i=1;i<=n;i++){
 7         cin>>x>>y;
 8       if(x>y){
 9           v[i]=2*(x-y);
10           w[i]=1;
11           tot+=x-y;
12         }
13         if(y>x){
14             v[i]=2*(y-x);
15             w[i]=-1;
16             tot+=y-x;
17         }
18     }
19     for(int i=1;i<=n;i++)
20       for(int j=1;j<=tot;j++){
21           dp[i][j]=dp[i-1][j];
22           vs[i][j]=vs[i-1][j];
23           if(vs[i-1][j-v[i]]||j-v[i]==0){
24               if(!vs[i][j]){
25                   dp[i][j]=dp[i-1][j-v[i]]+w[i];
26                   vs[i][j]=1;
27                 }
28                 else dp[i][j]=min(dp[i][j],dp[i-1][j-v[i]]);
29             }
30         }
31     for(int i=tot;i>=i;i--)
32       if(vs[n][i]){
33           cout<<base+dp[n][i];
34           return 0;
35         }
36 } 
View Code

 

以上是关于P1212 多米诺骨牌的主要内容,如果未能解决你的问题,请参考以下文章

Luogu 1282 多米诺骨牌

[luoguP1282] 多米诺骨牌(DP + 背包)

具现化骨牌描述递归方法-递归判断

多米诺骨牌题解

在 scala 中键入安全的多米诺骨牌

P1282 多米诺骨牌