zoukankan      html  css  js  c++  java
  • 多米诺骨牌

    传送门

    这道题要求我们在差最小的情况下反转次数最少。我们用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('
    ')
    
    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
    ",ans);
        return 0;
    }
  • 相关阅读:
    使用animate()完成修改图片src切换图片的动画效果
    一键分享到各个SNS插件
    $data[$i++]+=2;不等于$data[$i++]=$data[$i++]+2;
    QQ在线客服的使用
    JQuery实时监控文本框字符变化
    迭代器的使用
    泛型的作用
    Eclipse的使用
    关于“类型”字段的处理
    java servlet+mysql全过程(原创)
  • 原文地址:https://www.cnblogs.com/captain1/p/9859325.html
Copyright © 2011-2022 走看看