noi online 普及组

1.

模拟+剪枝 

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{

    int n;
    int a,b,c;
    scanf("%d",&n);
    a=n/14;
    b=n/14;
    c=n/14;
    if (n==1||n==2||n==5)
    {
        printf("-1");
        return 0;
    }
    else if (n%14==1)
    {
        c--;
        b=b+2;
    }
    else if (n%14==2)
    {
        a=a+3;
        c--;
    }
    else if (n%14==3)
    {
        a++;
    }
    else if (n%14==4)
    {
        b++;
    }
    else if (n%14==5)
    {
        c--;
        a=a+4;
    }
    else if (n%14==6)
    {
        a=a+2;
    }
    else if (n%14==7)
    {
        a++;
        b++;
    }
    else if (n%14==8)
    {
        b=b+2;
    }
    else if (n%14==9)
    {
        a=a+3;
    }
    else if (n%14==10)
    {
        a=a+2;
        b=b+1;
    }
    else if (n%14==11)
    {
        a=a+1;
        b=b+2;
    }
    else if (n%14==12)
    {
        a=a+4;
    }
    else if (n%14==13)
    {
        a=a+3;
        b=b+1;
    }
    printf("%d %d %d",c,b,a);
    return 0;
}

2.

其实就是分拆数问题。分拆数问题本质上是 n 也无标号的第二类斯特林数问题(第二类斯特林数是 n 有标号但是 k 无标号)。

那么对于这个问题,考虑两种 dp.

  • 1、令 f_{i,j}fi,j 表示对于 i 拆分成若干个不大于 j 的数的方案数。则有转移:

f_{i,j}=f{i,j-1}+f{i-j,j}

后面一项 f_{i-j,j}fij,j 可以看成一个背包一样,后面的状态对前面的状态有天然的累加效应,所以只需要考虑丢掉一个 jj 的情况;而前面一项则把我们转移从后一项的等于 jj 升级成为不大于 jj 。

  • 2、令 g{i,j} 表示对于 ii 拆分成 jj 个数的方案数。则有转移:

g_{i,j}=g_{i-1,j-1}+g_{i-j,j}gi,j=gi1,j1+gij,j

#include <bits/stdc++.h>
#define  LL long long
using namespace std;
const int N = 100005;
int f[N];
int g[400][N];
int main() {
    int n, p;
    cin >> n >> p;
    int m = sqrt(n) + 1;
    f[0] = 1;
    for (int i = 1; i < m; i++) {
        for (int j = i; j <= n; j++) {
            f[j] += f[j - i];
            f[j] %= p;
        }
    }
    g[0][0] = 1;
    for (int i = 1; i < m; i++) {
        for (int j = i; j <= n; j++) {
            g[i][j] = g[i][j - i];
            if (j >= m) g[i][j] += g[i - 1][j - m];
            g[i][j] %= p;
        }
    }
    int ans = 0;
    for (int i = 0; i <= n; i++) {
        LL sum = 0;
        for (int j = 0; j < m; j++) sum += g[j][n - i];
        sum %= p;
        ans = (ans + f[i] * sum) % p;
    }
    cout << ans << endl;
    return 0;
}

3.

矩阵快速幂优化DP(还没写完回来补
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const LL INF = 0x3f3f3f3f3f3f3f3f;
const int N = 100;
typedef LL Matrix[N][N];
int sz;
LL a[N][N];
void matrix_mul(Matrix A, Matrix B, Matrix res) {
    Matrix C;
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j < sz; j++) {
            C[i][j] = INF;
            for (int k = 0; k < sz; k++) {
                C[i][j] = min(C[i][j], A[i][k] + B[k][j]);

            }
        }
    }
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j < sz; j++) {
            res[i][j] = C[i][j];

        }
    }
}
void matrix_pow(Matrix A, LL p, Matrix res) {
    Matrix x;
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j < sz; j++) {
            x[i][j] = A[i][j];

            res[i][j] = a[i][j];

        }
    }
    while (p) {
        if (p & 1) matrix_mul(res, x, res);
        p >>= 1;
        matrix_mul(x, x, x);
    }
}

struct Edge {
    int u, v, w;
} b[2505];

int main() {
    int n, m, K;
    scanf("%d%d%d", &n, &m, &K);
    sz = n;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            a[i][j] = i == j ? 0 : INF;
    for (int i = 0; i < m; i++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        u--;
        v--;
        b[i] = {u, v, w};
        a[u][v] = min(a[u][v], (LL)w);

    }
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = min(a[i][j], a[i][k] + a[k][j]);

            }
        }
    }
    Matrix c;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            c[i][j] = a[i][j];

            for (int k = 0; k < m; k++) {
                c[i][j] = min(c[i][j], a[i][b[k].u] - b[k].w + a[b[k].v][j]);

            }
        }
    }
    matrix_pow(c, K, c);
    printf("%lld\n", c[0][n - 1]);
    return 0;
}


猜你喜欢

转载自www.cnblogs.com/Heartbeat358/p/12507268.html