51nod 1202 子序列个数

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202
d p [ i ] 表示计算到第 i 个的子序列个数
①:如果第 i 个这个数 x 是没出现过的,那么所有的子序列就是:原来 i 1 的所有子序列 + 把所有原来 i 1 的子序列的最后一位换成 x ,再 + x 这个数单独作为一个子序列
那么转移方程就是
d p [ i ] = d p [ i ] + d p [ i ] + 1
②:如果这个数是出现过的,那么所有子序列就是:原来 i 1 的所有子序列 + 把所有原来 i 1 的子序列的最后一位换成 x ,还要减去重复的,
比如有 1 , 2 , 3 , 4 , 5 , 4
1 , 2 , 3 所有的子序列: { 1 } , { 2 } , { 3 } , { 1 , 2 } , { 1 , 3 } , { 2 , 3 } , { 1 , 2 , 3 } 后面再加一个 4 的情况 { 1 , 4 } , { 2 , 4 } , { 3 , 4 } , { 1 , 2 , 4 } , { 1 , 3 , 4 } , { 2 , 3 , 4 } , { 1 , 2 , 3 , 4 }
那么这个 4 到底是从前一个来还是从后一个来喃?两种情况只能选一种,而且从上面阔以得出,重复的就只有这里 7
所以转移方程是:
d p [ i ] = d p [ i 1 ] + d p [ i 1 ] d p [ 1 ]

我用的 m a p 来标记上一次出现的位置

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int MOD=1e9+7;
long long dp[maxn];
int main()
{
    int N;
    while(cin>>N)
    {
        map<int,int>Mp;
        memset(dp,0,sizeof(dp));
        int t;
        for(int i=1;i<=N;i++)
        {
            cin>>t;
            if(Mp[t]==0)dp[i]=(dp[i-1]<<1)+1;
            else dp[i]=(dp[i-1]<<1)-dp[Mp[t]-1];
            dp[i]=(dp[i]+MOD)%MOD;
            Mp[t]=i;
        }
        cout<<dp[N]<<endl;
    }
}
全部评论

相关推荐

实在太美:小m嘛,干嘛要狠狠骂
点赞 评论 收藏
分享
#96年28岁其实挺小的#还没到28岁,不过也快了。没想到时间过得这么快,遥想大学毕业时我才23岁,读了个研,26了大学时我是一个风风火火的人,有想法&nbsp;有干劲&nbsp;有活力的人,觉得未来充满无限可能。我参加了很多的活动,也亲自作为负责人举办了全校规模的比赛,我体验了非常多不一样的事情,曾一度在一个星期内走遍了学校所有的男生宿舍去推销宣传产品,去校外拉赞助,谈''合作''&nbsp;锻炼了自己的口才,增长了自己的见识。现在想想,这些事好多都挺幼稚。但那个时候是我火一般的岁月,每天都充满激情。大学时不爱上课,所以文化课学的不怎么样,当时对这件事有遗憾,我没有高中时静心学习的能力了。后来,我想静...
大祥老师永远的0:徐霞客那一章作为七本书的尾声确实点睛之笔。 打开书时,个人的命运令我扼腕,王侯将相的事迹令我心潮澎湃,王朝的兴衰令我哀叹。 合上书后,最受用的还是最后一句话,幡然醒悟过来这些早已是过往云烟,你对它们扼腕、澎湃、哀叹其实轻于鸿毛,正如作者所言“先变成粪,后变成土”,用喜欢的方式度过自己的一生未必就不比书中的一个个名留青史的历史人物活得风采。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务