NC229192. 补幺梨
描述
输入描述
第一行,输入三个数 ,表示“补幺梨”的面值种数,基本货币的金额上限,以及随机种子。对于 ,“补幺人”通过下述 c++ 程序的 mt19937 随机数得到(需 c++11):int main() { scanf("%d%d%d", &n, &m, &seed); mt19937 rng(seed); auto get = [&]() { uniform_int_distribution<int> qwq(2, m); return qwq(rng); }; for (int i = 1; i <= n; i++) { a[i] = get(); } }
输出描述
你需要帮补幺人计算出最大不能被表示的面额。
不难发现,在给定的数据范围下,必定存在不能被表示的面额。
示例1
输入:
5 5 3
输出:
1
说明:
注意,样例仅作为参考。该数据范围不会出现在最终测试数据中。
生成的序列为4 2 4 5 3。最大不能被表示的金额显然是1。
示例2
输入:
2 100 10
输出:
2309
说明:
生成的序列为78 31。最大不能被表示的金额是2309。示例3
输入:
3 100 10
输出:
89
说明:
生成的序列为78 31 4。最大不能被表示的金额是89。示例4
输入:
50 50000000 97
输出:
50215765
C++ 解法, 执行用时: 1889ms, 内存消耗: 83308K, 提交时间: 2021-10-18 19:05:43
#include<bits/stdc++.h> using namespace std; const int N=10000005; typedef long long LL; int n,m,seed,a[N],M; LL dis[N],ans; bool vs[N]; priority_queue<pair<LL,int> > q; int main() { scanf("%d%d%d", &n, &m, &seed);M=m;mt19937 rng(seed); auto get = [&]() {uniform_int_distribution<int> qwq(2, m);return qwq(rng);}; for(int i=1;i<=n;i++) a[i]=get(),M=min(M,a[i]); q.push(make_pair(0,0)); for(int i=1;i<M;i++) dis[i]=1e18; while(q.size()) { int x=q.top().second;q.pop(); if(vs[x]) continue;vs[x]=1; for(int i=1,y=(x+a[i])%M;i<=n;y=(x+a[++i])%M) if(dis[y]>dis[x]+a[i]) dis[y]=dis[x]+a[i],q.push(make_pair(-dis[y],y)); } for(int i=1;i<M;i++) ans=max(ans,dis[i]-M); printf("%lld",ans);return 0; }