码迷,mamicode.com
首页 > 其他好文 > 详细

多米诺骨牌

时间:2018-10-27 01:32:48      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:pre   queue   怎么   http   ace   char   targe   int   上下   

传送门

这道题要求我们在差最小的情况下反转次数最少。我们用dp[i][j]表示选取前i个股票,差值为j的最小反转。因为差最小是优先条件,所以我们完全可以找到最接近某一个值的点,取其最小反转次数。

那么dp[i][j] = min(dp[i-1][j+a[i]],dp[i-1][j-a[i]]+1),其中a[i]表示第i块骨牌上下点数之差(不是绝对值!!),所以你在取相反数的时候相当于反了过来。至于怎么解决负数的问题,好办,数据波动不超过5000,所以只要设置一个中间值(比如6000),把它设为开始开始DP,最后找一个最接近的即可。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar(‘\n‘)

using namespace std;
typedef long long ll;
const int M = 20005;
const int INF = 1000000009;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < 0 || ch > 9)
    {
    if(ch == -) op = -1;
    ch = getchar();
    }
    while(ch >= 0 && ch <= 9)
    {
    ans *= 10;
    ans += ch - 0;
    ch = getchar();
    }
    return ans * op;
}

int n,k,a[M],dp[1005][12005],x,y,minn = INF,ans;

int main()
{
    n = read();
    rep(i,1,n) x = read(),y = read(),a[i] = x - y;
    rep(i,0,n)
    rep(j,0,12000) dp[i][j] = INF;
    dp[0][6000] = 0;
    rep(i,1,n)
    {
    rep(j,1000,11000)
    {
        dp[i][j] = min(dp[i][j],dp[i-1][j+a[i]]);
        dp[i][j] = min(dp[i][j],dp[i-1][j-a[i]]+1);
    }
    }
    rep(j,1000,11000)
    {
    if(dp[n][j] == INF) continue;
    if(abs(6000 - j) < minn) minn = abs(6000-j),ans = dp[n][j];
    }
    printf("%d\n",ans);
    return 0;
}

 

多米诺骨牌

标签:pre   queue   怎么   http   ace   char   targe   int   上下   

原文地址:https://www.cnblogs.com/captain1/p/9859325.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!