zoukankan      html  css  js  c++  java
  • FZU 2129 子序列个数 (动态规划)

    题意:子序列的定义:对于一个序列a=a[1],a[2],......a[n]。则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<.....<pm<=n。

    例如4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。

    对于给出序列a,请输出不同的子序列的个数。(由于答案比较大,请将答案mod 1000000007)

    思路:设前i个数字的子序列数为f(i)。

               1.如果第i个数字在前i个数字里都没有出现过,那么,原来i-1个数字里面的子序列也是前i个数字的子序列,总共是f(i-1),而在原来i-1个数字的子序列每个的背后加一个a[i]也是新的子序列,总共是f(i-1)个,然后最后一个数字单独也可以组成一个新的子序列,是1个,因此这时f(i)=f(i)+f(i)+1。

               2.如果第i歌数字在前面i个数字里面出现过,那么f(i)=f(i)+f(i)-f(a[i]最后一次出现的位置-1)。因为这时候,单独一个a[i]的情况已经被计算过,于是没有了+1,而往a[i]最后一次出现的位置-1加上一个a[i]的情况也已经被计算过,一次要减掉。

    注意:遇到减号的时候取模时要加MOD再取模。

    #include<cstdio>
    #include<cstring>
    #define MOD 1000000007
    #define MAXN 1000005
    typedef long long LL;
    LL f[MAXN];
    int last[MAXN],a,n;
    int main()
    {
    	while(~scanf("%d",&n))
    	{
    		memset(last,0,sizeof(last));
    		f[0]=0;
    		for(int i=1;i<=n;++i)
    		{
                scanf("%d",&a);
    			f[i]=(f[i-1]<<1)%MOD;
    			if(!last[a]) last[a]=i,f[i]++;
    			else f[i]=(f[i]-f[last[a]-1]+MOD)%MOD,last[a]=i;
    		}
    		printf("%I64d
    ",f[n]%MOD);
    	}
    	return 0;
    }
  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/pangblog/p/3253827.html
Copyright © 2011-2022 走看看