洛谷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 多米诺骨牌 题解相关推荐

  1. 【动态规划】洛谷 P1282 多米诺骨牌

    [动态规划]洛谷 P1282 多米诺骨牌 时间限制: 1 Sec  内存限制: 128 MB 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下 ...

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

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

  3. 洛谷p1282多米诺骨牌

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

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

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

  5. P1282 多米诺骨牌题解

    [题目链接] P1282 [解题思路] 这道题我本来是想用贪心,用sort从大到小排序后,减去两张骨牌的差直到最小,结果却发现自己WA了. 很显然我的贪心是错误的,于是我后来就用了老师教的 dpdpd ...

  6. 洛谷 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 ...

  7. 洛谷P3237 [HNOI2014]米特运输 题解

    洛谷P3237 [HNOI2014]米特运输 题解 题目链接:P3237 [HNOI2014]米特运输 题意: 这题面是真的长啊 qwq 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为 ...

  8. P1282 多米诺骨牌

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

  9. C++ P1282 多米诺骨牌

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

最新文章

  1. [翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图...
  2. mysql通过查看跟踪日志跟踪执行的sql语句
  3. 一头扎进tomcat
  4. 关于lingo的@wrap函数
  5. linux grep sed awk
  6. linux 复制文件或者文件
  7. Android 客户端与服务器交互方式
  8. LNMP--Nginx代理详解
  9. mongodb多条件查询
  10. Xcode6中自动布局autolayout和sizeclass的使用
  11. 根据ip查询所在国家地区(国内外ip均适用)
  12. 用idea创建vue项目
  13. matlab实现zca去白化,白化算法
  14. 在图片上加滚动文字html,如何让文字在图片上滚动
  15. 我的wow血精灵圣骑士,晒晒
  16. 基于Java毕业设计缘梦书屋网站源码+系统+mysql+lw文档+部署软件
  17. ROS2编程基础课程--库
  18. html 页面地图不显示图片,Html显示地图 - 切切歆语的个人页面 - OSCHINA - 中文开源技术交流社区...
  19. 二进制与8,10,16转换
  20. windows下linux子系统(Ubuntu)配置(基础配置+zsh)

热门文章

  1. A045_jQuery案例实战_BootStrap
  2. Python基础学习(十二)标准库
  3. 三角形外接球万能公式_外接球半径常见的求法
  4. Linux搭建Discuz论坛
  5. Bluetooth SIG定义的标准Characteristics UUID
  6. js适配IOS代T时间戳转日期
  7. java租车系统维熵科技_维熵租车系统数据库
  8. linux搞笑图片,2017高考表情包(最新最全表情包合集)-高考表情包恶搞搞笑图片下载-西西软件下载...
  9. 1D/1D动态规划学习总结
  10. centos离线配置yun源