洛谷P1282 多米诺骨牌 题解
洛谷P1282 多米诺骨牌 题解
题目链接:P1282 多米诺骨牌
题意:
多米诺骨牌由上下 222 个方块组成,每个方块中有 1∼61\sim61∼6 个点。现有排成行的上方块中点数之和记为 S1S_1S1,下方块中点数之和记为 S2S_2S2,它们的差为 ∣S1−S2∣\left|S_1-S_2\right|∣S1−S2∣。如图,S1=6+1+1+1=9S_1=6+1+1+1=9S1=6+1+1+1=9,S2=1+5+3+2=11S_2=1+5+3+2=11S2=1+5+3+2=11,∣S1−S2∣=2\left|S_1-S_2\right|=2∣S1−S2∣=2。每个多米诺骨牌可以旋转 180°180°180°,使得上下两个方块互换位置。请你计算最少旋转多少次才能使多米诺骨牌上下 222 行点数之差达到最小。
对于图中的例子,只要将最后一个多米诺骨牌旋转 180°180°180°,即可使上下 222 行点数之差为 000。
注意到我们其实并不关心 S1,S2S_1,S_2S1,S2 的值,而是关心他们的差值
这个绝对值似乎不好处理,其实只要把正负的情况取个min就可以了
设 dp[i][j]dp[i][j]dp[i][j] 表示只考虑前 iii 个骨牌,差值为 jjj 时的最小翻转数
这里的 jjj 定义为 S1−S2S_1-S_2S1−S2 或者 S2−S1S_2-S_1S2−S1 其实没啥区别,不过下面代码为前者
不难发现
dp[i][j]=min(dp[i−1][j−a[i]+b[i]]+1,dp[i−1][j+a[i]−b[i]])dp[i][j]=\min(dp[i-1][j-a[i]+b[i]]+1,dp[i-1][j+a[i]-b[i]]) dp[i][j]=min(dp[i−1][j−a[i]+b[i]]+1,dp[i−1][j+a[i]−b[i]])
注意到差值最大 500050005000 ,为了避免乱七八糟讨论,就直接循环 −5000∼5000-5000 \sim 5000−5000∼5000 就好啦
差值可能为负所以数组整体平移一下,然后整个填表法滚一滚啥的就好了
这里好像刷表法写起来不太安全就不写了,虽然没啥问题,但是不算简洁吧(逃
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(1e3+15)
const int bd=5e3+15;
int n,dp[2][20*N],a[N],b[N];
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);// freopen("check.in","r",stdin);// freopen("check.out","w",stdout);memset(dp,0x3f,sizeof(dp));cin >> n;dp[0][bd]=0;for(int i=1; i<=n; i++)cin >> a[i] >> b[i];for(int i=1; i<=n; i++){int cur=i&1,pre=cur^1;memset(dp[cur],0x3f,sizeof(dp[cur]));for(int j=-5000; j<=5000; j++)dp[cur][j+bd]=min(dp[pre][j+a[i]-b[i]+bd]+1,dp[pre][j-a[i]+b[i]+bd]);}for(int i=0; i<=5000; i++){int t=min(dp[n&1][i+bd],dp[n&1][-i+bd]);if(t<=n)return cout << t << endl,0;}return 0;
}
转载请说明出处
洛谷P1282 多米诺骨牌 题解相关推荐
- 【动态规划】洛谷 P1282 多米诺骨牌
[动态规划]洛谷 P1282 多米诺骨牌 时间限制: 1 Sec 内存限制: 128 MB 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下 ...
- 【01背包】洛谷P1282多米诺骨牌
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...
- 洛谷p1282多米诺骨牌
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...
- 洛谷 [P1282] 多米诺骨牌
这道题是一道背包问题,考虑一个背包, 显然如果我们直接设dp[i]表示前i个使差值最小所需的最少翻转次数,是具有后效性的. 所以我们将直接求最值,改为求某个值是否可行,这种求最值转变为求可行性的思想是 ...
- P1282 多米诺骨牌题解
[题目链接] P1282 [解题思路] 这道题我本来是想用贪心,用sort从大到小排序后,减去两张骨牌的差直到最小,结果却发现自己WA了. 很显然我的贪心是错误的,于是我后来就用了老师教的 dpdpd ...
- 洛谷 1282 多米诺骨牌#线性动态规划#
分析 状态转移方程:f[i+1][j+a[i]]=max(f[i][j]),f[i+1][j+b[i]]=max(f[i][j]+1)f[i+1][j+a[i]]=max(f[i][j]),f[i+1 ...
- 洛谷P3237 [HNOI2014]米特运输 题解
洛谷P3237 [HNOI2014]米特运输 题解 题目链接:P3237 [HNOI2014]米特运输 题意: 这题面是真的长啊 qwq 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为 ...
- P1282 多米诺骨牌
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...
- C++ P1282 多米诺骨牌
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...
最新文章
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图...
- mysql通过查看跟踪日志跟踪执行的sql语句
- 一头扎进tomcat
- 关于lingo的@wrap函数
- linux grep sed awk
- linux 复制文件或者文件
- Android 客户端与服务器交互方式
- LNMP--Nginx代理详解
- mongodb多条件查询
- Xcode6中自动布局autolayout和sizeclass的使用
- 根据ip查询所在国家地区(国内外ip均适用)
- 用idea创建vue项目
- matlab实现zca去白化,白化算法
- 在图片上加滚动文字html,如何让文字在图片上滚动
- 我的wow血精灵圣骑士,晒晒
- 基于Java毕业设计缘梦书屋网站源码+系统+mysql+lw文档+部署软件
- ROS2编程基础课程--库
- html 页面地图不显示图片,Html显示地图 - 切切歆语的个人页面 - OSCHINA - 中文开源技术交流社区...
- 二进制与8,10,16转换
- windows下linux子系统(Ubuntu)配置(基础配置+zsh)
热门文章
- A045_jQuery案例实战_BootStrap
- Python基础学习(十二)标准库
- 三角形外接球万能公式_外接球半径常见的求法
- Linux搭建Discuz论坛
- Bluetooth SIG定义的标准Characteristics UUID
- js适配IOS代T时间戳转日期
- java租车系统维熵科技_维熵租车系统数据库
- linux搞笑图片,2017高考表情包(最新最全表情包合集)-高考表情包恶搞搞笑图片下载-西西软件下载...
- 1D/1D动态规划学习总结
- centos离线配置yun源