/*反思:之前做这道题就想着是单纯的dp 然后复杂度 n*m*log(n) dp[i][j]表示更新到第i位总计交换k次得到的最大值
可是当时陷入误区 总觉得如果某一位交换了以后 就应该真的把a[i] b[i]交换,这样会影响以后的更新,当时没想到用树状数组来查找最大值,然后就用二分查,还需要维持数组的单调性,结果就导致了b[i]的更新会用到a[i]的结果 然后就各种凌乱。。
其实还是各种知识没法很好的结合在一起 就会单纯的用一种东西来解题 然后就解不出来
这道题本身还是很不错的 既练习dp 又用到了树状数组 还可以学习结构内定义函数 去重函数unique 查找函数lowerbound
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1009;
int nn;
int a[N],b[N];
int h[N * 2];
struct BIT{
int c[2*N];
int lowbit(int x){return x & -x;}
void update(int x, int k){
while(x <= nn){
c[x] = max(c[x], k);
x += lowbit(x);
}
}
int query(int x){
int ret = 0;
while(x > 0){
ret = max(ret ,c[x]);
x -= lowbit(x);
}
return ret;
}
}t[N]; //结构里定义函数 可以直接 t[i].update() 来调用,否则函数需要多传一个参数
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int m, n;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)
{
scanf("%d%d", &a[i], &b[i]);
h[i] = a[i]; h[i+n] = b[i]; //把所有的数都合并起来
}
sort(h, h + 2 * n);
nn = unique(h, h + 2 * n) - h; //排序 去重
for(int i = 0; i < n; i++)
{
a[i] = lower_bound(h, h + nn, a[i]) - h + 1;
b[i] = lower_bound(h, h + nn, b[i]) - h + 1; //将a[i],b[i]分别离散化
}
int ma = 1;
memset(t, 0, sizeof(t));
for(int i = 0; i < n; i++)
{
for(int j = m; j >= 0; j--)
{
int x1 = t[j].query(a[i] - 1) + 1; // 每次从[0,a[i])中寻找最大的数,然后当前位置的值等于查找到的值加一
if(x1 > ma) ma = x1;
t[j].update(a[i], x1); //通过树状数组更新值
if(j > 0) //如果j(变换次数)大于0,则用b[i]来寻找,之后同样
{
int x2 = t[j-1].query(b[i] - 1) + 1;
if(x2 > ma) ma = x2;
t[j].update(b[i], x2);
}
}
}
printf("%d\n", ma);
}
return 0;
}
hdu 5125题解
最新推荐文章于 2017-10-08 10:15:38 发布