zoukankan      html  css  js  c++  java
  • XJOI 3862 美丽序列

    题意

    福克斯喜欢整数序列,他认为一个序列美丽的定义是

    1.每个数都在(0)(40)之间

    2.每个数都小于等于之前的数的平均值

    具体地说:

    for each (i,1le i<N,A[i]le (A[0]+A[1]+...+A[i-1])/i).

    3.没有三个连续的递减的数

    现在给你一个序列,每个元素是(-1)(40),你可以将序列中的(-1)修改成任意的数,求你可以得到多少个美丽序列,答案对(1e9+7)取模

    输入格式

    第一行输入一个整数(n(1le nle 40))

    第二行输入(n)个整数

    输出格式

    输出一个整数

    样例输入1

    2
    3 -1
    

    样例输出1

    4
    

    样例输入2

    3
    5 3 -1
    

    样例输出2

    2
    

    样例输入3

    3
    -1 0 40
    

    样例输出3

    0
    

    样例输入4

    11
    -1 40 -1 -1 -1 10 -1 -1 -1 21 -1
    

    样例输出4

    579347890
    

    样例输入5

    6
    -1 12 25 0 18 -1
    

    样例输出5

    58
    

    分析

    不想贪心,暴力dp即可。

    因为数据范围极小,所以开四维dp数组,(dp[i][last][len][sum])表示第(i)个数是(last),前(i)个数组成的序列末尾的递减序列长度为(len),前(i)个数的和为(sum),则转移方程:(前缀(new)表示当前状态,不加表示上一个状态)

    (if;i>1;then{)

    (if;a[i]!=-1;then)

    (dp[i][a[i]][2][newsum]=sum dp[i-1][last][1][sum])

    (dp[i][a[i]][1][newsum]=sum dp[i-1][last][2][sum]+sum dp[i-1][last][1][sum])

    (else)

    (dp[i][newlast][2][newsum]=sum dp[i-1][last][1][sum])

    (dp[i][newlast][1][newsum]=sum dp[i-1][last][2][sum]+sum dp[i-1][last][1][sum])

    (})

    (else{)

    (if;a[1]!=-1;then)

    (dp[1][a[1]][1][a[1]]=1)

    (else)

    (dp[1][last][1][last]=1)

    (})

    Code

    #include<cstdio>
    #define maxn 45
    #define mod 1000000007ll
    #define PE(x,y) x=((x)+(y))%mod
    using namespace std;//dp[i][num_at_the_end][length_of_decreasing_sequence][sum]
    int a[maxn],n;
    long long dp[maxn][maxn][3][1605];
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	if(a[1]!=-1)dp[1][a[1]][1][a[1]]=1;
    	else{
    		for(int last=0;last<=40;last++){
    			dp[1][last][1][last]=1;
    		}
    	}
    	for(int i=2;i<=n;i++){
    		if(a[i]!=-1){
    			for(int sum=a[i]*(i-1);sum<=1600-a[i];sum++){
    				int newsum=sum+a[i];
    				for(int last=0;last<=40;last++){
    					if(a[i]<last){
    						PE(dp[i][a[i]][2][newsum],dp[i-1][last][1][sum]);
    					}
    					else{
    						PE(dp[i][a[i]][1][newsum],dp[i-1][last][2][sum]);
    						PE(dp[i][a[i]][1][newsum],dp[i-1][last][1][sum]);
    					}
    				}
    			}
    			continue;
    		}
    		for(int newlast=0;newlast<=40;newlast++){
    			for(int sum=newlast*(i-1);sum<=1600-a[i];sum++){
    				int newsum=sum+newlast;
    				for(int last=0;last<=40;last++){
    					if(newlast<last){
    						PE(dp[i][newlast][2][newsum],dp[i-1][last][1][sum]);
    					}
    					else{
    						PE(dp[i][newlast][1][newsum],dp[i-1][last][2][sum]);
    						PE(dp[i][newlast][1][newsum],dp[i-1][last][1][sum]);
    					}
    				}
    			}
    		}
    	}
    	long long ans=0;
    	for(int sum=0;sum<=1600;sum++){
    		for(int last=0;last<=40;last++){
    			for(int len=1;len<=2;len++){
    				PE(ans,dp[n][last][len][sum]);
    			}
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    启示:dp是除爆搜以外最暴力的算法……

  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/9862075.html
Copyright © 2011-2022 走看看