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;
    }
  • 相关阅读:
    visual studio 2019 企业版下载
    对IT战略的认识
    投融资,你了解吗?
    一品投资农副产品电商平台工作内容
    高明的决策和投资远比低效的勤奋更重要
    随笔
    思维方式的不同
    公司经营问题探讨
    盘点海口最好吃的西餐厅top10
    羽毛球运动技巧
  • 原文地址:https://www.cnblogs.com/captain1/p/9859325.html
Copyright © 2011-2022 走看看