51nod 1202 子序列个数
设 \(dp[i]\) 为第i个数不同子序列个数,先不考虑重复的情况,每个数只有选不选,转移方程为 \(dp[i]=dp[i-1]\times 2\),但现在我们要求的是不同的子序列个数,因此要减去重复的子序列个数。对于选取了 \(a_i\) 的子序列,会出现重复的序列一定是以某一个满足 \(a_j=a_i\) 的 \(a_j\) 结尾的,那么重复的子序列个数就是 \(dp[j-1]\),其中 \(j\) 是最大的满 \(a_j=a_i\) 并且 \(j<i\) 的数。
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+10; const int mod=1e9+7; int n,m; ll dp[N]; map<ll,ll> a; ll b[N]; int main(){ ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++){ cin>>b[i]; } dp[0]=1; for(int i=1;i<=n;i++){ dp[i]=(dp[i-1]*2-dp[a[b[i]]-1]+mod)%mod; a[b[i]]=i; } cout<<dp[n]-1; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通