ABC135

ABC135

B 暴力枚举交换

    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int cnt = 0;
    int flag = 0;
    for (int k = 1; k <= n - 1; k++)
    {
        if (a[k] >= a[k + 1])
            flag = 1;
    }
    if (!flag)
    {
        cout << "YES" << endl;
        return 0;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = i + 1; j <= n; j++)
        {
            memcpy(b, a, sizeof a);
            int flag = 0;
            swap(b[i], b[j]);
            for (int k = 1; k <= n - 1; k++)
            {
                if (b[k] >= b[k + 1])
                    flag = 1;
            }
            if (!flag)
            {
                cout << "YES" << endl;
                return 0;
            }
        }
    }
    cout << "NO" << endl;

C 贪心,尽量取 \(i\) 位置的值,而不取 \(i + 1\) 位置的值。注意 \(ll\)

    LL n;
    cin >> n;
    rep(i, n + 1) cin >> a[i];
    rep(i,n) cin >> b[i];
    LL ans = 0;
    rep(i,n + 1)
    {
        LL cnt = a[i] + a[i + 1];
        if(cnt >= b[i]) 
        {
            if(b[i] >= a[i]) 
            {
                LL _ = b[i] - a[i];
                a[i] = 0;
                a[i + 1] -= _;
                ans += b[i];
            }
            else 
            {
                a[i] -= b[i];
                ans += b[i];
            }
        }
        else 
        {
            ans += cnt;
            b[i] -= cnt;
            a[i] = 0;
            a[i + 1] = 0;
        }
    }
    cout << ans << endl;

D

dp 中的 sum 问题:

余数 给的很小,那么可以通过余数做做文章。

dp[i][j]表示到第 i 位时余数为 j 这样的数的个数

起始值:dp[0][0] = 0

答案:dp[n][5]

s[i] == 数字: dp[i][(j * 10 + s[i] - '0') % 13] = (dp[i][(j * 10 + s[i] - '0') % 13] + dp[i - 1][j])%mod;

(j * 10 + s[i] -'0') % 13是由 j 变换过来的,最后答案要加上 dp[i - 1][j]

s[i] == ? : 枚举 \(0 \sim 9\) 考虑 \(i\) 位置依次放置 \(0 \sim 9\) ,

dp[i][(j * 10 + k) % 13] = (dp[i][(j * 10 + k) % 13] + dp[i - 1][j]) % mod;

余数为 (j * 10 + k) % 13是由 j 变换过来的,所以最后的答案中要加上 dp[i - 1][j]的值

余数变换是不变的,如 27 % 13 == 1,(27 * 10) % 13 == 10 == 1 * 10

那么就可以直接乘上 \(i - 1\) 位置的余数 + 当前 \(i\) 位置的值再取余数是不变的。

LL dp[N][100];
char s[N];
int main()
{
    scanf("%s", s + 1);
    dp[0][0] = 1;
    int n = strlen(s + 1);
    for (int i = 1;i <= n;i++)
    {
        if (s[i] >= '0' && s[i] <= '9')
        {
            for (int j = 0; j < 13; j++)
            {
                dp[i][(j * 10 + s[i] - '0') % 13] = (dp[i][(j * 10 + s[i] - '0') % 13] + dp[i - 1][j])%mod;
            }
        }
        else
        {
            for (int j = 0; j < 13;j++)
            {
                for (int k = 0; k <= 9;k++)
                {
                    dp[i][(j * 10 + k) % 13] = (dp[i][(j * 10 + k) % 13] + dp[i - 1][j]) % mod;
                }
            }
        }
    }
    cout << dp[n][5] << endl;
    return 0;
}

posted @ 2020-04-01 00:15  strategist_614  阅读(173)  评论(0编辑  收藏  举报