Dominoes

http://poj.org/problem?id=1717

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

题解:

dp,背包,翻转或者不翻转,然后f[i][j],j表示反转后差为j的最小次数。

有点意思

/*
*@Author:   STZG
*@Language: C++
*/
//#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG

using namespace std;
typedef long long ll;
const int N=10000+10;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 1000000007;
int t,n,m;
int a[N/10+10][2],dp[N/10+10][N];
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i][0],&a[i][1]);
    memset(dp,127,sizeof(dp));
    dp[0][5000]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<=10000;j++)
            if(dp[i][j]<INF){
                int x1=a[i+1][0],x2=a[i+1][1];
                dp[i+1][j+x1-x2]=min(dp[i][j],dp[i+1][j+x1-x2]);
                dp[i+1][j+x2-x1]=min(dp[i][j]+1,dp[i+1][j+x2-x1]);
            }
    for(int i=0;i<=5000;i++)
        if(dp[n][5000+i]<INF||dp[n][5000-i]<INF)
        {
            printf("%d\n",min(dp[n][5000+i],dp[n][5000-i]));
            break;
        }
    //cout << "Hello world!" << endl;
    return 0;
}

 

全部评论

相关推荐

06-08 22:25
门头沟学院 Java
从零开始的转码生活:这hr不会打开手机不分青红皂白给所有人群发这句话,过一会再给所有人再发一遍,这肯定会有重复的,不管,再过一会再发一遍
点赞 评论 收藏
分享
熊大不大:哈哈,你就说你是男生,也是受害者
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务