BZOJ2298: [HAOI2011]problem a
这题长得很邪乎,表示一眼啥也看不出来
然而是在讲 dp 的课件上看到的,依然看不出来是 dp
于是去颓题解
大概是没往这个模型方面想
我们把一个人说的话用线段表示出来
线段左右端点分别为 : ai + 1, n - bi
表示这一段人分数相同
若有相交或包含的线段那其中必然矛盾
完全相等的线段我们将其合并, 并将线段的权值 + 1
线段的权值不能大于线段长度,因为不会有超过线段长度的人考同一个分数
从样例也可以看出来,线段左端点不能大于右端点 或 ai + bi <= n
枚举一个右端点,用所有以当前点为右端点的线段和当前线段左端点 -1 的位置的 f值 更新 f[i]
代码:
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cctype> #include<cstdio> #include<vector> #include<map> using namespace std; const int MAXN = 100005; int n; int f[MAXN]; map<pair<int,int>, int> mp; vector<int> seg[MAXN]; int main() { scanf("%d", &n); register int xx, yy; pair<int, int> dst; for(int i = 1; i <= n; ++i) { scanf("%d%d", &xx, &yy); xx += 1; yy = n - yy; if(xx > yy) continue; dst = make_pair(xx, yy); mp[dst] = ((mp[dst] == yy - xx + 1) ? (mp[dst]) : (mp[dst] + 1)); if(mp[make_pair(xx, yy)] == 1) seg[yy].push_back(xx); } for(int i = 1; i <= n; ++i) { f[i] = f[i - 1]; for(int j = 0; j < seg[i].size(); ++j) { f[i] = max(f[i], f[seg[i][j] - 1] + mp[make_pair(seg[i][j], i)]); } } printf("%d\n", n - f[n]); return 0; }
STL常数大
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/