• [haoi2009]逆序对数列


    对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数。若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数。那么逆序对数为k的这样自然数数列到底有多少个?

     n<=1000,k<=1000 

    题解:很明显的动态规划题目;

    设f[i][j]表示使长度为i的,只含数字1-i的序列,逆序对数有j个的方案数;

    我们在转移的时候很好操作,假如此时正在求f[i][j],那么我们枚举这个1-i序列的最后一位数字,假设这个数字是k,那么f[i][j]+=f[i-1][j-(i-k)],i-k表示若最后一位数字为k对逆序对的贡献;

    这么搞是O(n2m)的,1000的数据量会T;

    可以看到每次f[i][j]的结果是f[i-1]的结果中的一段和,那么就可以记录下当前的sum=(f[i-1][head]+f[i-1][head+1]...+f[i-1][tail]),这样每次换j的时候调整一下区间的左右端点就好了;

    总复杂度O(nm);

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<algorithm>
    #include<cstdlib>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define FILE "1"
    #define LL long long 
    #define up(i,j,n) for(int i=j;i<=n;i++)
    #define pii pair<int,int>
    #define piii pair<int,pair<int,int> >
    template<typename T> inline bool chkmin(T &a,T b){return a>b?a=b,true:false;}
    template<typename T> inline bool chkmax(T &a,T b){return a<b?a=b,true:false;}
    namespace IO{
        char *fs,*ft,buf[1<<15];
        inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
        inline int read(){
            LL x=0;int ch=gc();bool f=0;
            while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();}
            while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
            return f?-x:x;
        }
    }using namespace IO;
    namespace OI{
        const int maxn(1100),mod(10000);
        int f[maxn][maxn];
        int n,m;
        void slove(){
            n=read(),m=read();
            f[1][0]=1;
            for(int i=2;i<=n;i++){
                int sum=0,head=0,tail=-1;
                f[i][0]=1;
                for(int j=1;j<=m;j++){
                    while(j-i+1>head)sum=(sum-f[i-1][head]+mod)%mod,head++;//控制左右端点的移动
                    while(tail<j)tail++,sum=(sum+f[i-1][tail])%mod;
                    f[i][j]=sum;
                }
            }
            cout<<f[n][m]<<endl;
            return;
        }
    }
    int main(){
        freopen(FILE".in","r",stdin);
        freopen(FILE".out","w",stdout);
        using namespace OI;
        slove();
        return 0;
    }
    
        
  • 相关阅读:
    求相同号码一天内的上网流量——mapreduce
    scala初学
    对web日志文件实现按照人员、行为分类
    08 ROS阶段总结——package.xml 和 CMakeLists.txt 详细解读
    06 ROS中的节点、话题和服务
    07 ROS 的常见消息类型
    01 ROS下的三维点云数据处理(一)点云数据来源
    01 Opencv系列(一)ROS和opencv图像数据的转换
    01 ROS的运行架构——环境变量和工作空间
    02 Opencv系列(二)ROS框架下的摄像头调用方法
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6000889.html
Copyright © 2020-2023  润新知