zoukankan      html  css  js  c++  java
  • 【BZOJ2699】更新 动态规划

    【BZOJ2699】更新

    Description

           对于一个数列A[1..N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A[i],最后A[1]为所求最大值。假设所有数都在范围[1, K]内,按上面的步骤执行,有多少个长度N的数列满足A[1]被更新的次数恰好为P呢?

    Input

           本题有多组数据。输入第一行一个数T为数据组数,下面T行每行依次三个数N、K和P。

    Output

           对每组数据输出一行,为方案数模1000000007的值。
     
    输入 输出 解释
    3
    4 3 2
    2 3 1
    3 4 1
    6
    3
    30
    对第一组数据N=4, K=3, P=2, 所有满足的序列有下面六种:
    1) {1,1,2,3}   2) {1,2,1,3}
    3) {1,2,2,3}   4) {1,2,3,1}
    5) {1,2,3,2}   6) {1,2,3,3}
     
    数据范围
           前20%的数据满足T ≤ 5
    前50%的数据满足1 ≤ N ≤ 50,1 ≤ K ≤ 100
           对100%的数据,T ≤ 1000,1 ≤ N ≤ 150,0 ≤ P < N,1 ≤ K ≤ 300

    题解:傻题。。

    用f[i][j][k]表示前i个数,最大值为j,已经被更新了k次的方案数。然后用前缀和优化转移即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    typedef long long ll;
    const ll P=1000000007;
    int T,n,m,p;
    int f[160][310][160];
    int main()
    {
    	int i,j,k;
    	for(i=1;i<=300;i++)	f[1][i][0]=i;
    	for(i=2;i<=150;i++)
    	{
    		for(k=0;k<=150;k++)
    		{
    			for(j=1;j<=300;j++)
    			{
    				if(k)	f[i][j][k]=f[i-1][j-1][k-1];
    				f[i][j][k]=(f[i][j][k]+1ll*j*(f[i-1][j][k]-f[i-1][j-1][k]+P)%P+f[i][j-1][k])%P;
    			}
    		}
    	}
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d%d",&n,&m,&p);
    		printf("%d
    ",f[n][m][p]);
    	}
    	return 0;
    }
  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7787747.html
Copyright © 2011-2022 走看看