Journey

https://codeforces.com/contest/1476/problem/D

题意

\(n + 1\) 个点和它们之间连接关系, 两点之间是单向的, 每走过一条边, 所有的边反向, 问从某个点开始出发, 能走过的最长的路径是多少

思路

一开始以为要建图, 实际上算是线性dp

  • \(用\ l[i]\ 表示\ i\ 往左最多走几步\)
  • \(用\ r[i]\ 表示\ i\ 往右最多走几步\)
  • \(因为走过一条边, 其他边反向, 所以当\ s[i]=='L'\ s[i-1]=='R'\ ,\ i\ 可以走到\ i-2,因此\ l[i] += l[i-2]+1\)
  • \(同理\ s[i + 1] == 'R'\ s[i+2] == 'L'\ 时, \ r[i]+=r[i+2]+1\)
  • \(每条边的最长路径:ans=l[i]+r[i]+1\)
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define pb push_back
#define PII pair<int, int>
#define fi first
#define se second
#define inf 0x3f3f3f3f
const int N = 3e5 + 7;
char s[N];
int l[N], r[N];

int main() {
    IO;
    int _;
    cin >> _;
    while (_--) {
        memset(l, 0, sizeof l);
        memset(r, 0, sizeof r);
        int n;
        cin >> n;
        cin >> s + 1;
        for (int i = 1; i <= n; ++i) 
            if (s[i] == 'L') {
                l[i] = 1;
                if (i >= 2 && s[i - 1] == 'R') l[i] += l[i - 2] + 1;
            }
        for (int i = n - 1; i >= 0; --i) 
            if (s[i + 1] == 'R') {
                r[i] = 1;
                if (i + 2 <= n && s[i + 2] == 'L') r[i] += r[i + 2] + 1;
            }
        for (int i = 0; i <= n; ++i) cout << l[i] + r[i] + 1 << " ";
        cout << '\n';
    }
    return 0;
}


posted @ 2021-02-01 00:19  phr2000  阅读(59)  评论(0)    收藏  举报