题目大意:
给定正整数序列
Cn
和一个正整数
V
,求出一组非负整数解
分析:
对于
n=1
的情况不说了。
对于
n=2
的情况我们扩展欧几里得一下,然后调整成和为最小的。
对于
n=3
的情况,我们枚举一个
X
,其余两个
AC code:
#include <cstdio>
#include <algorithm>
#include <iostream>
typedef long long LL;
using namespace std;
const LL INF = 1LL<<60;
namespace math
{
LL gcd(LL a, LL b)
{
while(b) b^=a^=b^=a%=b;
return a;
}
LL ext_gcd(LL a, LL b, LL &x, LL &y)
{
if(!b)
{
x = 1, y = 0;
return a;
}
LL ret = ext_gcd(b, a%b, x, y);
LL tmp = x;
x = y, y = tmp-a/b*y;
return ret;
}
bool adjust(LL a, LL b, LL &x, LL &y)
{
LL g = gcd(a, b);
LL kx = b/g, ky = a/g;
if(x < 0)
{
y -= ((-x-1)/kx+1)*ky;
x += ((-x-1)/kx+1)*kx;
}
if(y < 0)
{
x -= ((-y-1)/ky+1)*kx;
y += ((-y-1)/ky+1)*ky;
}
if(x < 0 || y < 0) return false;
if(kx < ky)
{
x += y/ky*kx;
y -= y/ky*ky;
}
else if(kx > ky)
{
y += x/kx*ky;
x -= x/kx*kx;
}
return true;
}
}
bool solve(LL a, LL b, LL &x, LL &y, LL v)
{
LL ret, gcd = math::gcd(a, b);
if(v%gcd != 0) return false;
math::ext_gcd(a, b, x, y);
x *= v/gcd, y *= v/gcd;
return math::adjust(a, b, x, y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
LL n, a[5] = {0}, v;
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i];
cin >> v;
LL ans = 0;
LL x, y;
if(n == 1)
{
if(v%a[1] == 0) ans = v/a[1];
else ans = -1;
}
else if(n == 2)
{
if(solve(a[1], a[2], x, y, v)) ans = x+y;
else ans = -1;
}
else
{
ans = INF;
for(int i = v/a[3]; i >= 0; --i)
if(solve(a[1], a[2], x, y, v-i*a[3]))
ans = min(ans, x+y+i);
if(ans == INF) ans = -1;
}
cout << ans << endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}