• 最少多少人说谎(dp)


    https://ac.nowcoder.com/acm/contest/1168/H

    题意:n个学生,邓志聪想知道这些学生的考试情况,于是一个一个叫这些学生叫去办公室问他们,但是有些学生并没有讲真话,第i个学生说:“有ai个人分数比我高,bi个人分数比我低。”邓志聪想知道最少有几个学生没有说真话,你能帮助他吗?(可能有相同的分数)

    解法:逆向思维求最多有多少人没说谎,用区间代表该名同学所处的位置,区间值代表该区间人数。

    dp求解不重叠区间值之和最大即可。

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    #define mod 20191117
    #define PI acos(-1)
    using namespace std;
    typedef long long ll ;
    
    map<pair<int , int > , int>m;
    vector<int>ans[100100];
    int dp[100100];
    
    int main()
    {
        int n ;
        scanf("%d" , &n);
        for(int i = 0 ; i < n ; i++)
        {
            int x , y ;
            scanf("%d%d" , &x , &y);
            int l = x + 1 ;//高的在左
            int r = n - y ;//低的在右
            if(l > r) continue;
            if(m[make_pair(l , r)] < r - l + 1)
                m[make_pair(l , r)]++;//区间值代表人数
            if(m[make_pair(l , r)] == 1) ans[r].push_back(l);
        }
        for(int i = 1 ; i <= n ; i++)
        {
            dp[i] = dp[i -1];//i为右边界。
            for(auto j : ans[i])//ans[i]中第二维中的元素的左边界
            {
                dp[i] = max(dp[i] , dp[j-1] + m[make_pair(j , i)]);
            }
        }
        cout << n - dp[n] << endl ;
        return 0;
    }
    
  • 相关阅读:
    信息探测
    Hdu 1262 寻找素数对
    Hdu 1263 水果
    Hdu 1261字串数
    Hdu 1253 胜利大逃亡
    Hdu 1237简单计算器
    Hdu 1235 统计同成绩学生人数
    Hdu 1236 排名
    Hdu 1233 还是畅通工程
    Hdu 1234 开门人和关门人
  • 原文地址:https://www.cnblogs.com/nonames/p/11932919.html
Copyright © 2020-2023  润新知