洛谷 P1282 多米诺骨牌

本文介绍了一种利用动态规划解决多米诺骨牌翻转问题的方法,旨在找到最少翻转次数使骨牌两行点数之差最小。算法通过状态转移方程进行求解,最终给出最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目概述

    多米诺骨牌有上下2个方块组成,每个方块中有1~6个点。现有排成行的n个骨牌,每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置,求出最少的旋转次数使多米诺骨牌上下2行点数之差达到最小。

    1<=n<=1000

解题思路

    这题采用动态规划的思路,f[i,j]代表前i个骨牌能够组成差值为j的最小翻转次数,初始化最大值,f[0,0]=0;

    状态转移方程为f[i,j]=min(f[i-1,j+a[i,3]+1,f[i-1,j-a[i,3]);(a[i,3]为第i个骨牌上下数字的差值)

    注意边界,差值可能为负数。

    时间复杂度:O(12000n)

    空间复杂度:O(12000n)

源程序

var
 a:array[1..1002,1..3]of longint;
 b:array[0..1002,-6006..6006]of integer;
 i,n,sum1,sum2,j,t,ans,l:longint;
function minx(a,b:longint):longint;
 begin
  if a<b then exit(a)
         else exit(b);
 end;
begin
 readln(n);
 sum1:=0;
 sum2:=0;
 for i:=1 to n do
  begin
   readln(a[i,1],a[i,2]);
   a[i,3]:=a[i,1]-a[i,2];
  end;
  fillchar(b,sizeof(b),$7f);
 b[0,0]:=0;
 for i:=1 to n do
  begin
   for j:=-6000 to 6000 do
    b[i,j]:=minx(b[i-1,j+a[i,3]]+1,b[i-1,j-a[i,3]]);
  end;
 ans:=b[n,0];
 l:=0;
 if b[n,0]>10000 then
  while l<6000 do
   begin
    inc(l);
    if (b[n,l]<10000)and(ans>b[n,l]) then ans:=b[n,l];
    if (b[n,-l]<10000)and(ans>b[n,-l]) then ans:=b[n,-l];
    if (b[n,l]<10000)or(b[n,-l]<10000)then break;
   end;
 write(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值