[Training] 20,191,001 solving Jinan report

(death..)

Only 30 points. .

The first two questions fairly normal, the first question of number theory + half the answer, and I burst open again array (life and death bearish), the second question dp (Actually, I think analog is also okay, that is, if too much about his own success gosh)

The third question. . Well, look at the title bar. .

The first feeling is certainly violence, part of this question a lot points, k = 0 can be solved with a full backpack. (30 points)

Yes I just watched this question. .

The second feeling. . Probably dp

However, geese, positive solution of this problem is the shortest path , Dijkstra and SPFA will do. .

I? ? ? ? (Black question mark)

It is the teacher's explanation

This is the teacher program

#include<bits/stdc++.h>
#define A 20001
#define N 5001
using namespace std;
typedef long long ll;
struct node {
    int x; ll v;
    bool operator < (const node &oth) const {
        return v > oth.v;
    }
};
priority_queue<node>q;
int pre[A], n, m, K, vis[A];
ll a[N], dis[A], sum[N];
ll getin() {
    ll s = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c <= '9' && c >= '0') s = s * 10ll + c - '0', c = getchar();
    return s;
}
void dijkstra() {
    for (int i = 1; i < a[1]; i++) dis[i] = 1e18;
    dis[0] = 0;
    q.push((node) {0, 0});
    while (!q.empty()) {
        int u = q.top().x;
        q.pop();
        if (vis[u]) continue;
        vis[u] = true;
        for (int i = 1; i <= n; i++) {
            int v = (u + a[i]) % a[1];
            if (dis[u] + a[i] < dis[v]) {
                dis[v] = dis[u] + a[i];
                pre[v] = i, q.push((node){v, dis[v]});
            }
        }
    }
}
int main() {
    freopen("equip.in", "r", stdin);
    freopen("equip.out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; i++) a[i] = getin();
    dijkstra();
    for (int i = 1; i <= m; i++) {
        ll x = getin();
        if (x < dis[x % a[1]]) printf("No\n");
        else {
            printf("Yes");
            if (K == 1) {
                for (int j = 1; j <= n; j++) sum[j] = 0;
                sum[1] += (x - dis[x % a[1]]) / a[1];
                while (x % a[1]) {
                    sum[pre[x % a[1]]]++;
                    x = ((x - a[pre[x % a[1]]]) % a[1] + a[1]) % a[1];
                }
                for (int j = 1; j <= n; j++) printf(" %I64d", sum[j]);
            }
            printf("\n");
        }
    }
    return 0;
}

(I understand incompetent ...)

and so! I would like a way easier to understand!

Use column indeterminate equation solver

For each equipment m, column Equations

n1x1+n2x2+n3x3+……+nnxn=m

Solving like

(The time before the n-1 each as a whole using the extended Euclidean line Solution)

A little more than the time complexity of larger Shortest

(The program will have time to write, to the tune would impress)

Guess you like

Origin www.cnblogs.com/Daz-Os0619/p/11616165.html