遗忘的记忆
[题目链接](https://www.nowcoder.com/practice/8246aab6553d4384ba5f4090101762ef)
思路
有 篇分享,每篇的点赞量为
的正整数。给定一个长度为
的字符串
,其中
为
<、= 或 >,描述第 篇和第
篇点赞量的大小关系。求满足所有约束的点赞量序列有多少种,答案对
取模。
动态规划 + 前缀和
定义 表示第
篇分享点赞量为
时的合法方案数。
初始状态:,对所有
。
转移:根据 的字符,从
转移到
:
- 若
<(第篇严格大于第
篇):
$$
即 的前缀和,到
为止。
- 若
>(第篇严格小于第
篇):
$$
即 的后缀和,从
开始。
- 若
=(第篇等于第
篇):
$$
对于 < 和 > 的情况,前缀和与后缀和可以在遍历 的过程中累加维护,无需额外数组,单次转移
。
最终答案为 。
样例演示
输入
<=>:
- 初始:
(对应
)
- 经过
<:(前缀和偏移一位)
- 经过
=:(不变)
- 经过
>:(后缀和偏移一位)
- 答案
复杂度分析
- 时间复杂度:
,共
次转移,每次遍历
个值。
- 空间复杂度:
,使用滚动数组优化,只保留当前一行。
代码
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
string s;
if(n > 1) cin >> s;
vector<long long> dp(m + 2, 0);
for(int j = 1; j <= m; j++) dp[j] = 1;
for(int i = 0; i < (int)s.size(); i++){
vector<long long> ndp(m + 2, 0);
if(s[i] == '<'){
long long pre = 0;
for(int j = 1; j <= m; j++){
ndp[j] = pre;
pre = (pre + dp[j]) % MOD;
}
} else if(s[i] == '>'){
long long suf = 0;
for(int j = m; j >= 1; j--){
ndp[j] = suf;
suf = (suf + dp[j]) % MOD;
}
} else {
for(int j = 1; j <= m; j++){
ndp[j] = dp[j];
}
}
dp = ndp;
}
long long ans = 0;
for(int j = 1; j <= m; j++) ans = (ans + dp[j]) % MOD;
cout << ans << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final int MOD = 1000000007;
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
String s = "";
if (n > 1) s = sc.next();
long[] dp = new long[m + 2];
for (int j = 1; j <= m; j++) dp[j] = 1;
for (int i = 0; i < s.length(); i++) {
long[] ndp = new long[m + 2];
char c = s.charAt(i);
if (c == '<') {
long pre = 0;
for (int j = 1; j <= m; j++) {
ndp[j] = pre;
pre = (pre + dp[j]) % MOD;
}
} else if (c == '>') {
long suf = 0;
for (int j = m; j >= 1; j--) {
ndp[j] = suf;
suf = (suf + dp[j]) % MOD;
}
} else {
for (int j = 1; j <= m; j++) {
ndp[j] = dp[j];
}
}
dp = ndp;
}
long ans = 0;
for (int j = 1; j <= m; j++) ans = (ans + dp[j]) % MOD;
System.out.println(ans);
}
}

京公网安备 11010502036488号