AtCoder Beginner Contest 211(补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 211(补题)相关的知识,希望对你有一定的参考价值。

C - chokudai


题意: 问字符串s有多少个子序列,是字符串t “chokudai”.
思路: 动态规划问题,设置 d p f [ i , j ] dpf[i,j] dpf[i,j]为取前长度为i的字符串s,与字符串t前长度为j匹配的数量。
那么此时,状态转移方程官方题解,不想再手打了

由于字符串t下标是从0开始的,所以下面的代码,方程转移会有小变化。
笔记:这个解法,适用于所有寻找字符串s中找有多少个子序列t(在不超时的情况下)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10, mod = 1e9 + 7;
char s1[N];
char s2[] = "chokudai";
int f[N][10];
int main() {
    scanf("%s", s1 + 1);
    int len = strlen(s1 + 1);
    f[0][0] = 1;
    for (int i = 1; i <= len; i++) {
        for (int j = 0; j <= 8; j++) {
            f[i][j] = f[i - 1][j];
        }
        for (int j = 0; j < 8; j++) {
            if (s2[j] == s1[i]) {
                f[i][j + 1] = (ll)f[i][j + 1] + f[i - 1][j] % mod;
            }
        }
    }
    printf("%d\\n", f[len][8]);
    return 0;
}

D - Number of Shortest paths



题意: 问从1到N的最短路的路径数(裸模板题)
思路: 边权为1,基础最短路路径数的题,也可以开vector来存边

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2 * 2e5 + 10, mod = 1e9 + 7;
queue<int> q;
int n, m;
int e[N], ne[N], h[N], idx;
int path[N], dis[N], vis[N];
void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }

int main() {
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof(h));
    for (int i = 0; i < m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y), add(y, x);
    }
    path[1] = 1;
    q.push(1);
    while (q.size()) {
        int t = q.front();
        q.pop();
        for (int i = h[t]; i != -1; i = ne[i]) {
            int j = e[i];
            if (!vis[j]) {
                vis[j] = 1;
                dis[j] = dis[t] + 1;
                q.push(j);
            }
            if (dis[j] == dis[t] + 1) {
                path[j] = (ll)(path[j] + path[t]) % mod;
            }
        }
    }
    printf("%d\\n", path[n]);
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6 + 10, mod = 1e9 + 7;
queue<int> q;
int n, m;
int e[N], ne[N], h[N], idx;
pair<int, int> f[N];
void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }

int main() {
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof(h));
    for (int i = 0; i < m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y), add(y, x);
    }
    f[1] = make_pair(0, 1);
    for (int i = 2; i <= n; i++) {
        f[i] = make_pair(1e9, 0);
    }
    q.push(1);
    while (!q.empty()) {
        int t = q.front();
        q.pop();
        for (int i = h[t]; i != -1; i = ne[i]) {
            int x = e[i];
            if (f[x].first > f[t].first + 1) {
                f[x] = f[t];
                f[x].first++;
                q.push(x);
            } else if (f[x].first == f[t].first + 1) {
                f[x].second = (ll)(f[x].second + f[t].second) % mod;
            }
        }
    }
    printf("%d\\n", f[n].second);
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于AtCoder Beginner Contest 211(补题)的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242