51nod 1202 子序列个数

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

我用的 map 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;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值