洛谷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°,使得上下两个方块互换位置。 编程用最少的旋转次数使多米诺骨牌上下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

Solution

先打了个搜索?45分

#include<bits/stdc++.h>
using namespace std;
const int N=1010,inf=2e9;
int n,tot,ans=inf,tq=inf;
int a[N],b[N];
void dfs(int x,int sum,int cnt) {
if(x==n+1) {
if(abs(tot-sum-sum)<ans) ans=abs(tot-sum-sum),tq=cnt;
else if(abs(tot-sum-sum)==ans) tq=min(tq,cnt);
return;
}
dfs(x+1,sum+a[x],cnt);
dfs(x+1,sum+b[x],cnt+1);
}
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i],tot+=a[i]+b[i];
dfs(1,0,0);
cout<<tq<<endl;
}

为什么要贴这份代码,因为我们可以把我们搜索中记录的变量变成dp中的状态(一位dalao告诉我的做dp的方法?)

我们发现因为当题目给出塔牌的点数后,无论是否翻转,前i张牌的上下点数之和是不变的,那么我们知道一个就可以求出另一个

ok?我们现在来设计\(dp\)数组,按照搜索中的变量,设dp[i][j]表示到第i张纸牌,第一行的和为j的翻转次数

那么状态转移方程就呼之欲出了?

\(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)\) 翻转

我们发现这样转移可能会越界?那就加个条件嘛

  if(j-a[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]]);
if(j-b[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-b[i]]+1);

那么初始化,第二维最大可能是6*n(每张都是6点),所以初始化

for(int i=1;i<=n;i++)
for(int j=0;j<=6*n;j++) dp[i][j]=inf;

然后就是dp边界

dp[1][b[1]]=1,dp[1][a[1]]=0;//为什么是这个顺序,因为如果先a后b,那么当第一张纸牌上下点数相同时,dp[1][a[1]]会被赋值成1

最后枚举一下点数统计答案就可以了,和dfs一样

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1010,inf=2e5;
int n,tot,ans=inf,tq=inf;
int a[N],b[N],dp[N][6*N];
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i],tot+=a[i]+b[i];
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*n;j++) {
if(j-a[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]]);
if(j-b[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-b[i]]+1);
}
}
for(int i=0;i<=tot;i++) {
if(dp[n][i]!=inf) {
if(abs(tot-i-i)<ans)
ans=abs(tot-i-i),tq=dp[n][i];
else if(abs(tot-i-i)==ans) tq=min(tq,dp[n][i]);
}
}cout<<tq<<endl;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

洛谷P1282 多米诺骨牌 (DP)的更多相关文章

  1. 洛谷P1282 多米诺骨牌

    P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S ...

  2. poj 1717==洛谷P1282 多米诺骨牌

    Dominoes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6571   Accepted: 2178 Descript ...

  3. 【01背包】洛谷P1282多米诺骨牌

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  4. 洛谷 P1282 多米诺骨牌 ( 线性DP )

    题意 : 题目链接 分析 :  一开始这个想法也有想到,但是貌似要开很大数组,就感觉应该不行 遂放弃想其他方法,万万没想到注意到可以滚动优化(其实不优化也可以过) 定义 dp[i][j] 表示 到第 ...

  5. 洛谷P1282 多米诺骨牌【线性dp】

    题目:https://www.luogu.org/problemnew/show/P1282 题意: 给定n个牌,每个牌有一个上点数和下点数.可以通过旋转改变交换上下点数. 问使得上点数之和和下点数之 ...

  6. 洛谷 P1282 多米诺骨牌("01"背包)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://blog.csdn.net/Darost/artic ...

  7. 洛谷 [P1282] 多米诺骨牌

    这道题是一道背包问题,考虑一个背包, 显然如果我们直接设dp[i]表示前i个使差值最小所需的最少翻转次数,是具有后效性的. 所以我们将直接求最值,改为求某个值是否可行,这种求最值转变为求可行性的思想是 ...

  8. yzoj P2043 & 洛谷 P1282 多米诺骨牌 题解

    题意 类似于就是背包. 解析 代码 跟解析有点不一样v[i]价值,w[i]重量,s背包容积,背包转移即可. #include<bits/stdc++.h> using namespace ...

  9. P1282 多米诺骨牌 dp

    思路:dp[i][j] 的j是上半段的和的值   这里表示的是达到上半段值是j的最小次数 答案在最小的可达到的j #include<bits/stdc++.h> using namespa ...

随机推荐

  1. 常用 css html 样式

    CSS基础必学列表 CSS width宽度 CSS height高度 CSS border边框 CSS background背景 CSS sprites背景拼合 CSS float浮动 CSS mar ...

  2. 工作中使用的linux命令汇总

    ln -s  /usr/local/tomcat/ ./tomcat   创建软连接到/usr/local/tomcat tar -zxvf apache-kylin-2.4.0-bin-hbase1 ...

  3. PHP环境搭建-记录

    转于 http://jingyan.baidu.com/article/fcb5aff797ec41edaa4a71c4.html php5.5 做了大量的更新,在与apache搭配的时候如何选择也很 ...

  4. nyoj 525 一道水题【字符串(分割)】

    参考:https://blog.csdn.net/dxx_111/article/details/48154687 #include <iostream> #include <cst ...

  5. Linux系统下安装rz/sz命令

    执行命令 yum install -y lrzsz rz -be本地上传文件到服务器

  6. webpack入门概念

    一 概念 1 入口(entry) 入口起点(entry point)提示webpack 应该使用那个模块,来作为构建其内部依赖图得开始.进入入口七点后,webpack 会找出那些模块和库是入口起点(直 ...

  7. LeetCode:3.Longest Substring Without Repeating Characters

    思路:看到题目首先想到最大字符串匹配KMP算法 public static int lengthOfLongestSubstring(String s) { int maxLength = 0; St ...

  8. 安装cloudera manager使用mysql作为元数据库

    1.首次安装好mysql数据库后,会生成一个随机密码,使用如下办法找到: cat /var/log/mysqld.log |grep password 2.首次安装好mysql数据库后,第一次登陆进去 ...

  9. thrift 调取 python php go 客户端代码

    golang package main import ( "fmt" "git.apache.org/thrift.git/lib/go/thrift" &qu ...

  10. Android 序列化比对

    本文转自:https://www.zybuluo.com/linux1s1s/note/91046 注:部分内容有更改 在Android中使用序列化,无非两种途经: Parcelable 和 Seri ...