题目链接:子序列个数
思路:使用一个数组(map超时了)记录一个数字在之前出现的位置,然后状态转移方程有两个,如果一个数字在之前出现过:dp[i] = (dp[i - 1] * 2 - dp[index[temp] - 1] + MOD) % MOD;,如果没有出现过:dp[i] = (dp[i - 1] * 2 + 1) % MOD;,这里注意减法取余需要加上MOD,否则可能出现负数。
dp这种东西,看比想容易的多了...23333我看懂了.....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <stdio.h> #include <string.h> #include <iostream> #define mod 1000000007 using namespace std; int index[1000010]; long long dp[1000010]; int main() { int n; while (~scanf( "%d" , &n)) { memset(index, -1, sizeof (index)); memset(dp, 0, sizeof (dp)); dp[1] = 1; int temp; scanf( "%d" , &temp); index[temp] = 1; for ( int i=2; i<=n; ++i) { scanf( "%d" , &temp); if (index[temp] == -1) { dp[i] = (((dp[i-1]%mod)*2)%mod+1)%mod; } else { dp[i] = (((dp[i-1]%mod)*2)%mod-dp[index[temp]-1]+mod)%mod; } index[temp] = i; } printf( "%d\n" , dp[n]); } return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步