zoukankan      html  css  js  c++  java
  • bzoj1109:[POI2007]堆积木Klo

    传送门

    自己想的方向一直是对的,但是一直没有完全正确
    我一直没发现可以缩掉一维
    原本列出的dp方程是这样的
    (f[i]=f[j]+1(j<i&&a[j]<a[i]&&j-a[j]<=i-a[i]))(f[i])代表(i)移动到正确位置,前(i)个最多有多少个到正确位置)
    看着就是lis,实际上想也可以想得到lis是最优的
    然后你会发现满足后两个要求就满足了第一个要求,那么我们就可以按照(i-a[i])排序,然后做lis就行了
    PS.不可能移动到原位的显然不用考虑,判掉就行了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    #define lowbit(i) (i&(-i))
    const int maxn=1e6+10;
    int n,f[maxn],ans,mx,now;struct oo{int x,id;}a[maxn];
    void add(int x,int y){for(rg int i=x;i<=mx;i+=lowbit(i))f[i]=max(f[i],y);}
    int get(int x){int ans=0;for(rg int i=x;i;i-=lowbit(i))ans=max(ans,f[i]);return ans;}
    bool cmp(oo x,oo y){return x.id==y.id?x.x<y.x:x.id<y.id;}
    int main()
    {
    	read(n);
    	for(rg int i=1;i<=n;i++)read(a[i].x),a[i].id=i-a[i].x,mx=max(mx,a[i].x);
    	sort(a+1,a+n+1,cmp);
    	for(rg int i=1;i<=n;i++)if(a[i].id>=0)now=get(a[i].x-1)+1,ans=max(ans,now),add(a[i].x,now);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    zoj 3627#模拟#枚举
    Codeforces 432D Prefixes and Suffixes kmp
    hdu 4778 Gems Fight! 状压dp
    CodeForces 379D 暴力 枚举
    HDU 4022 stl multiset
    手动转一下田神的2048
    【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律
    poj 3254 状压dp
    C++中运算符的优先级
    内存中的数据对齐
  • 原文地址:https://www.cnblogs.com/lcxer/p/10409321.html
Copyright © 2011-2022 走看看