• [USACO11FEB]Generic Cow Protests


    题目传送门

    一道挺好的数据结构优化DP的题目,树状数组搞一搞就好了。

    sol

    讲下思路,首先看了眼数据范围 (1≤N≤10^5) ,暴力很好写吧,(O(n^2))的线性dp

    for(int i=1;i<=n;i++)scanf("%d",&f[i]),s[i]=s[i-1]+f[i];//统计一下前缀和
    dp[0]=1;
    for(int i=1;i<=n;i++){
    	for(int j=0;j<i;j++){
    		if(s[i]-s[j]>=0)dp[i]+=dp[j],dp[i]%=mod;//线性dp
    	}
    }
    printf("%d
    ",dp[n]);//目标dp[n]
    

    然后我们发现

    前缀和数组(s_i),dp数组(f_i),最终答案为(f_n)
    那么怎么计算答案呢,看下样例(其中(0≤i≤n))

    (i) 0 1 2 3 4
    (a_i) 0 2 3 -3 1
    (s_i) 0 2 5 2 3

    因为数的范围为(-10^5 ≤ Ai ≤ 10^5),所以需要离散化一下防止RE,设离散化数组为(r_i),也就是每个(s_i)的排名

    (i) 0 1 2 3 4
    (r_i) 1 2 4 2 3

    因为要保证(s_i≥s_j)((1≤i≤n,0≤j<i)),(f_i)加上之前比他小的有多少方案(其实就是一个加法原理)
    我们设值域为数的种类,建立一个树状数组,其中第(r_i)位表示这个数之前有多少个数小于等于他,画个图理解一下

    (i)=0时,直接加上

    (i)=1时,因为(r_1)=2,所以在第二个位置加入,又因为在第二个位置前有1个数加入,所以第二个位置的值为1

    (i)=2时,因为(r_2)=4,所以在第四个位置加入,又因为在第四个位置前有2个数加入,所以第二个位置的值为2

    注意当(i)=3时,(r_3)=2,从前出现过,但还是一样,在第二个位置加入,先统计,再加入

    因为第二个位置之前有2个数加入,所以在第二个位置加上2,故

    (i)=4时,以此类推,所以最后的答案为4

    cpp

    #include<bits/stdc++.h>
    #define mod 1000000009
    using namespace std;
    const int maxn=1e5+10;
    typedef long long ll;
    int n;
    int tree[maxn];
    inline int lowbit(int x){return x&(-x);}//树状数组基本操作 
    void add(int x,int d){for(int i=x;i<=1e5+10;i+=lowbit(i))tree[i]+=d,tree[i]%=mod;}//添加操作 记得取模 
    inline int sum(int x){ll sum=0;for(;x;x-=lowbit(x))sum+=tree[x],sum%=mod;return sum;}//求和操作 记得取模 
    int s[maxn],f[maxn];//s为前缀和 
    ll ans;
    int b[maxn];//离散化数组 
    int main(){
    	scanf("%d",&n);
    	for(int i=1,x;i<=n;i++)scanf("%d",&x),s[i]=s[i-1]+x,b[i]=s[i];//用离散化的数组记录起来 
    	sort(b,b+n+1);
    	for(int i=0;i<=n;i++)s[i]=lower_bound(b,b+n+1,s[i])-b+1;//离散化 
    	add(s[0],1);//s[0]方案数为1 
    	for(int i=1;i<=n;i++){
    		ans=sum(s[i]);//查询在s[i]前有多少小于等于它的数 
    		add(s[i],ans);//加入到树状数组中 
    	}
    	printf("%lld
    ",ans%mod);//记得取模 
    	return 0;
    }
    

    完结撒花,欢迎大佬爆锤我。

  • 相关阅读:
    构建之法:第二次心得
    构建之法:第一次心得
    tomcat配置限制ip和建立图片服务器
    tomcat8.5优化配置
    java 操作 csv文件
    jsoup教学系列
    (转)js实现倒计时效果(年月日时分秒)
    本地启动tomcat的时候报java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
    使用mybatis执行oracle存储过程
    java 获取web登录者的ip地址
  • 原文地址:https://www.cnblogs.com/qzwer/p/13196637.html
Copyright © 2020-2023  润新知