• 【洛谷5204】[USACO19JAN] Train Tracking 2 P(DP)


    点此看题面

    • 有一个值域为([1,10^9])的整数序列,给出每相邻(k)个元素中的最小值,求原序列可能的个数。
    • (nle10^5)

    (a_i)全相同时的(DP)

    方便起见记(w=10^9-a_i)

    那也就是说,至多隔(k)个位置选择一次(a_i),而不选(a_i)的时候有(w)种选法。

    因此设(f_i)表示第(i)个位置选择了的方案数,得出暴力转移式:

    [f_i=sum_{j=i-k}^{i-1}f_j imes w^{i-j-1} ]

    我们发现转移的系数是(w^{i-j-1}),因此考虑把(f_{i-1})乘上(w),发现:

    [f_{i-1} imes w=sum_{j=i-k-1}^{i-2}f_j imes w^{i-j-1} ]

    它和(f_i)只有(f_{i-k-1})(f_{i-1})两项不同,稍微补正一下即可:

    [f_i=f_{i-1} imes (w+1)-f_{i-k-1} imes w^k ]

    这样就可以(O(n))(DP)了。

    (a_i)不相同时的分段拆解

    对于(a_i)全相同的一段([i,j]),粗略考虑它在原序列中管辖的区间为([i,j+k-1]),长度为(j-i+k)

    但是,如果(a_{i-1}>a_i),说明(s_{i+k-1}=a_i),且(s_{isim i+k-2})肯定全都大于等于(a_{i-1}),因此当前段管辖区间大小减少(k)

    同理,如果(a_{j+1}>a_i),说明(s_j=a_i),且(s_{j+1sim j+k-1})肯定全都大于等于(a_{j+1}),因此当前段管辖区间大小减少(k)

    然后发现不同的管辖区间之间是独立的,分别按照前面的方法(DP)然后把方案数相乘即可。

    代码:(O(n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define INF 1000000000
    #define X 1000000007
    using namespace std;
    int n,k,a[N+5];I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
    int f[N+5];I int DP(CI x,CI n)//动态规划
    {
    	RI i,w=INF-x,p=QP(w,k);f[0]=f[1]=1;//初始化
    	for(i=2;i<=n+1;++i) f[i]=(1LL*f[i-1]*(w+1)-(i>k?1LL*f[i-k-1]*p%X:0)+X)%X;return f[n+1];//利用f[i-1]*w高效转移
    }
    int main()
    {
    	RI i,j,p;for(scanf("%d%d",&n,&k),i=1;i<=n-k+1;++i) scanf("%d",a+i);
    	RI t=1,o;for(i=1;i<=n-k+1;i=j+1) {j=i;W(a[j+1]==a[i]) ++j;o=j-i+k-(a[i-1]>a[i])*k-(a[j+1]>a[i])*k,t=1LL*t*DP(a[i],o)%X;}//根据a[i]分段拆解
    	return printf("%d
    ",t),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    dubbo系列五、dubbo核心配置
    dubbo系列四、dubbo服务暴露过程源码解析
    dubbo系列三、架构介绍及各模块关系
    dubbo系列二、dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台)
    dubbo系列一、dubbo背景介绍、微服务拆分
    Python "HTTP Error 403: Forbidden"
    UnicodeEncodeError: ‘gbk’ codec can’t encode character u’u200e’ in position 43: illegal multib
    pycharm 激活
    Win7 在安装vs2010后向sql2008添加SQL_Server_Management详解
    vs2010,vs2012如何连接vss2005,vss2008
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5204.html
Copyright © 2020-2023  润新知