zoukankan      html  css  js  c++  java
  • B1786 [Ahoi2008]Pair 配对 逆序对+dp

    这个题有点意思,一开始没想到用dp,没啥思路,后来看题解才恍然大悟:k才1~100,直接枚举每个-1点的k取值进行dp就行了。先预处理出来sz[i][j]  i左边的比j大的数,lz[i][j]  i右边比j小的数。然后就没啥了。

    题干:

    Description

    Input

    Output

    Sample Input

    5 4
    4 2 -1 -1 3

    Sample Output

    4
    代码:
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int n,m,tot = 0;
    int a[10020],num[10020];
    int lz[10050][105];
    int sz[10020][105];
    int dp[10020][105];
    int k;
    int main()
    {
        read(n);read(k);
        duke(i,1,n)
        {
            read(a[i]);
            if(a[i] == -1)
            num[++tot] = i;
        }
        duke(i,1,n) 
        {
            duke(j,1,k)
            {
                if(a[i - 1] > j)
                    sz[i][j] = sz[i - 1][j] + 1;
                else
                    sz[i][j] = sz[i - 1][j];
            }
        }
        lv(i,n - 1,1)
        {
            duke(j,1,k)
            {
                if(a[i + 1] < j && a[i + 1] != -1)
                    lz[i][j] = lz[i + 1][j] + 1;
                else
                    lz[i][j] = lz[i + 1][j];
            }
        }
        duke(i,1,n)
        {
            duke(j,1,k)
            {
                if(a[i] != -1)
                {
                    dp[i][j] = dp[i - 1][j];
                    continue;
                }
                else
                {
                    dp[i][j] = INF;
                    duke(l,1,k)
                    {
                        dp[i][j] = min(dp[i - 1][l] + lz[i][j] + sz[i][j],dp[i][j]);
                    }
                }
            }
        }
        int ans = INF;
        duke(i,1,k)
        {
            ans = min(ans,dp[n][i]);
        }
        duke(i,1,n)
        {
            if(a[i] != -1)
            {
                ans += sz[i][a[i]];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    /*
    5 4
    4 2 -1 -1 3
    */
  • 相关阅读:
    HTTP客户端
    获取IP地址和域名
    SQL语句、PL/SQL块和SQL*Plus命令之间的区别
    oracle中的游标
    oracle表问题
    精简版web浏览器
    oracle的存储过程
    数据库中的视图
    第一次作业
    折半查找
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9525359.html
Copyright © 2011-2022 走看看