济南集训20191001解题报告
Posted daz-os0619
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了济南集训20191001解题报告相关的知识,希望对你有一定的参考价值。
(死亡。。)
只有30分。。
前两题还算正常,第一题数论+二分答案,我又又又把数组开爆了(生死看淡),第二题dp(其实我觉得模拟也还行,就是if太多成功把自己绕晕)
第三题。。算了,先看题吧。。
第一感觉肯定是暴力,这道题部分分挺多,k=0的情况可以用完全背包解决。(30分)
没错我就是这一题有分。。
第二感觉。。可能是dp
然鹅,这题的正解是最短路,Dijkstra和SPFA都行。。
我????(黑人问号)
这是老师的解释
这是老师的程序
#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;
(我理解无能。。。)
所以!我想了一种更容易理解的方法!
利用列不定方程求解
对于每一个装备m,列方程有
n1x1+n2x2+n3x3+……+nnxn=m
求解就好
(每一次把前n-1个看成一个整体利用扩展欧几里得求解就行)
时间复杂度稍微比最短路大一点
(程序有时间会写,调对了就放上来)
以上是关于济南集训20191001解题报告的主要内容,如果未能解决你的问题,请参考以下文章