POJ 1717 Dominoes

105 篇文章 0 订阅

Description

A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank or bearing from one to six dots. There is a row of dominoes laid out on a table: 

The number of dots in the top line is 6+1+1+1=9 and the number of dots in the bottom line is 1+5+3+2=11. The gap between the top line and the bottom line is 2. The gap is the absolute value of difference between two sums. 

Each domino can be turned by 180 degrees keeping its face always upwards. 

What is the smallest number of turns needed to minimise the gap between the top line and the bottom line? 

For the figure above it is sufficient to turn the last domino in the row in order to decrease the gap to 0. In this case the answer is 1. 
Write a program that: computes the smallest number of turns needed to minimise the gap between the top line and the bottom line.

Input

The first line of the input contains an integer n, 1 <= n <= 1000. This is the number of dominoes laid out on the table. 

Each of the next n lines contains two integers a, b separated by a single space, 0 <= a, b <= 6. The integers a and b written in the line i + 1 of the input file, 1 <= i <= 1000, are the numbers of dots on the i-th domino in the row, respectively, in the top line and in the bottom one. 

Output

Output the smallest number of turns needed to minimise the gap between the top line and the bottom line.

Sample Input

4
6 1
1 5
1 3
1 2

Sample Output

1

Source

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

01背包~

翻车了……

记录一个maxx值表示上下最大差值。

用f[i][j]表示差值为j-maxx时的最小步数,如果f[i][j]==n表示不能得到这个差值。其中i这一维滚动。

用d(i)来表示i+maxx,结果最后求值的时候忘记了,写成了d(maxx+i)……WA到怀疑人生……所以一定要细心呀!


#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define d(u) (u+maxx)

int n,a[1001],maxx,f[2][20001],inf;
bool kkz;

int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f; 
}

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read()-read();
		maxx+=a[i]<0 ? -a[i]:a[i];
	}
	for(int i=0;i<=2*maxx;i++) f[kkz][i]=n+1;inf=n+1;
	f[kkz][d(a[1])]=0;f[kkz][d(-a[1])]=1;
	for(int i=2;i<=n;i++)
	{
		kkz^=1;
		for(int j=0;j<=2*maxx;j++) f[kkz][j]=n+1;
		for(int j=0;j<=2*maxx;j++)
		  if(f[kkz^1][j]!=inf)
		  {
		  	f[kkz][j+a[i]]=min(f[kkz][j+a[i]],f[kkz^1][j]);
			f[kkz][j-a[i]]=min(f[kkz][j-a[i]],f[kkz^1][j]+1);
		  }
	}
	for(int i=0;;i++)
	  if(f[kkz][d(i)]!=inf || f[kkz][d(-i)]!=inf)
	  {
	  	printf("%d\n",min(f[kkz][d(i)],f[kkz][d(-i)]));break;
	  }
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MATLAB中实现机械臂的仿真可以使用Robotic System Toolbox来进行。Robotic System Toolbox包含许多工具和函数,可以实现机械臂的建模、控制和仿真。 首先,需要定义机械臂的模型。可以使用robotics.RigidBodyTree类来创建机械臂的刚体树结构。通过添加关节和刚体可以构建机械臂的结构。可以使用函数robotics.RigidBody来创建刚体,并使用函数robotics.Joint来创建关节。 接下来,可以使用robotics.RigidBodyTree类中的函数来定义机械臂的初始状态。可以设置每个关节的初始位置和速度。 然后,可以使用robotics.RigidBodyTree类中的函数来进行机械臂的运动控制。可以使用函数robotics.InverseKinematics来实现逆运动学,根据目标位置和姿态来求解关节角度。可以使用函数robotics.CartesianTrajectory来生成机械臂的轨迹,指定起始和目标位置以及运动时间。 最后,可以使用robotics.RigidBodyTree类中的函数来进行机械臂的仿真。可以使用函数robotics.Rate来指定仿真的频率,然后使用循环来更新机械臂的状态和控制输入,实现机械臂的运动。 以下是一个基本的机械臂仿真的示例代码: ```matlab % 创建机械臂模型 robot = robotics.RigidBodyTree; % 添加机械臂的关节和刚体 % 设置机械臂的初始状态 % 运动控制 % 仿真循环 % 绘制机械臂的运动轨迹 ``` 在实际的机械臂仿真中,可能还需要考虑机械臂的动力学、碰撞检测和路径规划等问题。可以使用Robotic System Toolbox中的其他工具和函数来处理这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值