AtCoder Beginner Contest 275 D~F

D - Yet Another Recursive Function

思路:直觉需要用到的数字大多数是重复的,所以记忆化了一下,测了一下 1e18 的数据,跑的飞快,直接交了,6ms。

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb emplace_back
using namespace std;
using ll = long long;
using PII = pair<int, int>;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;

map <ll, ll> s;
ll dfs(ll x) {
    if(s.count(x))
        return s[x];
    else {
        s[x] = dfs(x / 2) + dfs(x / 3);
        return s[x];
    }
}
void solve() {
    s[0] = 1;
    ll x;
    cin >> x;
    cout << dfs(x);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    t = 1;
    
    while(t--) {
        solve();
    }
}

E - Sugoroku 4

思路:一个很简单的概率 dp,我不懂概率期望也会做……就对每一步分析,每个位置到能走到的位置的概率是均分的,dp 转移一下即可。

代码:

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb emplace_back
using namespace std;
using ll = long long;
using PII = pair<int, int>;
const int N = 2e5 + 10;
const int mod = 998244353;

int n, m, k;
void solve() {
    cin >> n >> m >> k;
    vector<ll> dp(n + 1);
    dp[0] = 1;
    for(int i = 1; i <= k; i++) {
        vector<ll> ndp(n + 1);
        for(int j = 0; j < n; j++) {
            for(int z = 1; z <= m; z++) {
                int to = j + z;
                if(to > n)
                    to = n - (to - n);
                ndp[to] = (ndp[to] + dp[j] * qpow(m, mod - 2) % mod) % mod;
            }
        }
        ndp[n] = (ndp[n] + dp[n]) % mod;
        dp = ndp;
    }
    cout << dp[n];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    t = 1;
    
    while(t--) {
        solve();
    }
}

F - Erase Subarrays

思路:也是一个 dp,三维的状态,第三维 0 和 1 分别表示走到这个位置和不走这个位置,然后就是简单的 dp 转移了,具体实现可以看代码。

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb emplace_back
using namespace std;
using ll = long long;
using PII = pair<int, int>;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;

int n, m;
int a[N];
int dp[3010][3010][2];
void solve() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    memset(dp, 0x3f, sizeof dp);
    dp[0][0][0] = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <= m; j++) {
            if(j + a[i] <= m) {
                dp[i][j + a[i]][0] = min(min(dp[i - 1][j][0], dp[i - 1][j][1]), dp[i][j + a[i]][0]);
            }
            dp[i][j][1] = min(min(dp[i - 1][j][1], dp[i - 1][j][0] + 1), dp[i][j][1]);
        }
    }
    for(int i = 1; i <= m; i++) {
        int res = min(dp[n][i][0], dp[n][i][1]);
        if(res > 1e6)
            cout << "-1\n";
        else 
            cout << res << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    t = 1;
    
    while(t--) {
        solve();
    }
}

 

posted @ 2022-10-31 16:47  Leonard7  阅读(44)  评论(0)    收藏  举报