2298: [HAOI2011]problem a

2298: [HAOI2011]problem a

链接

分析:

  每个人说的话,可以转化成区间[l,r]的人的排名是一样的,于是就转化成了区间带权覆盖问题。

  f[i]表示到第i个人,的最多有多少人说了真话,n-f[n]为答案。

  对于f[i],如果没有线段以i为右端点,f[i] = f[i-1]。

  如果有的话,那么这些线段可以选或不选,不选f[i]=f[i-1];选,它可以从最近的不想交的地方转移,找到此线段的左端点,然后f[i]=max(f[l]+min(w[l,i],i-l+1));w表示线段的权值,j-l+1,表示这条线段最大的价值。

  

  另一种写法:f[i]表示到第i条线段的最大价值,那么可以二分找到第一个不和这条线段相交的线段,从这里转移。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cctype>
 5 #include<map>
 6 #include<vector>
 7 #define mp(a,b) make_pair(a,b)
 8 #define pa pair<int,int>
 9
10 using namespace std;
11
12 const int N = 100100;
13
14 map < pa, int > w;
15 vector < int > q[N];
16 int f[N];
17
18 inline int read() {
19     int x = 0,f = 1;char ch=getchar();
20     for (; !isdigit(ch); ch=getchar()) if(ch==‘-‘)f=-1;
21     for (; isdigit(ch); ch=getchar()) x=x*10+ch-‘0‘;
22     return x*f;
23 }
24 int main() {
25     int n = read();
26     for (int i=1; i<=n; ++i) {
27         int a = read(),b = read();
28         int l = a + 1,r = n - b; // 注意!
29         if (l > r) continue;
30         if (w[mp(l,r)] == 0) q[r].push_back(l);
31         w[mp(l,r)] ++;
32     }
33     for (int r=1; r<=n; ++r) {
34         f[r] = f[r-1]; // 不选
35         int sz = q[r].size();
36         for (int i=0; i<sz; ++i) {
37             int l = q[r][i];
38             f[r] = max(f[r],f[l-1]+min(w[mp(l,r)],r-l+1)); // 选
39         }
40     }
41     cout << n - f[n];
42     return 0;
43 }

原文地址:https://www.cnblogs.com/mjtcn/p/9162109.html

时间: 2024-11-09 06:19:34

2298: [HAOI2011]problem a的相关文章

BZOJ 2298: [HAOI2011]problem a 动态规划

2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=2298 Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Outp

bzoj 2298: [HAOI2011]problem a

Description 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Output 一个整数,表示最少有几个人说谎 Sample Input 3 2 0 0 2 2 2 Sample Output 1 HINT 100%的数据满足: 1≤n≤100000   0≤ai.bi≤n Source 首先我们需要对问题进

BZOJ 2298: [HAOI2011]problem a【动态规划】

Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Output 一个整数,表示最少有几个人说谎 Sample Input 32 00 22 2Sample Output1HINT 100%的数据满足: 1≤n≤100000   0≤ai.bi≤n 思路:很明显,有x人比他成绩好,y个人比他成绩差,那剩下

BZOJ 2302: [HAOI2011]Problem c( dp )

dp(i, j)表示从i~N中为j个人选定的方案数, 状态转移就考虑选多少人为i编号, 然后从i+1的方案数算过来就可以了. 时间复杂度O(TN^2) --------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long lo

[BZOJ 2301] [HAOI2011] Problem b

2301: [HAOI2011]Problem b Time Limit: 50 SecMemory Limit: 256 MB Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Output 共n行,每行一个整数表示满足要求的数对(x,y)的个数 Sample Input 2 2 5 1 5

BZOJ 2301([HAOI2011]Problem b-mobius反演)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2170  Solved: 934 [Submit][Status][Discuss] Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Out

BZOJ 2301 [HAOI2011]Problem b (容斥+莫比乌斯反演+分块优化 详解)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2096  Solved: 909 [Submit][Status][Discuss] Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Out

HAOI2011 problem b

其实就是容斥原理了 代码: 1 uses math; 2 const maxn=55000; 3 var i,n,a,b,c,d,w,tot:longint; 4 ans:int64; 5 sum,mu,p:array[0..maxn] of int64; 6 procedure get; 7 var i,j,k:longint; 8 check:array[0..maxn] of boolean; 9 begin 10 fillchar(check,sizeof(check),false);

BZOJ 2302: [HAOI2011]Problem c [DP 组合计数]

2302: [HAOI2011]Problem c Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 648  Solved: 355[Submit][Status][Discuss] Description 给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了,就尝试ai+1,ai+1也被占据了的话就尝试ai+2,……,如果一直