UVA10090 数论基础 exgcd

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1031

题目大意:有n块大理石,然后有两种盒子,cost分别为c1,c2,容量分别为n1,n2,问你装完这些大理石所需要的最小花费是多少

思路分析:设最终选择x个第一种盒子,y个第二种盒子

根据题目,有 n1*x+n2*y=n ,让求T=c1*x+c2*y的最小值

解不定方程,容易想到使用exgcd ,n1*x0+n2*y0=gcd(n1,n2)

比较两式即可得到x=n*x0/gcd(n1,n2),y=n*y0/gcd(n1,n2)

结果肯定为正整数么,若n%gcd(n1,n2)!=0,则无解

通解为 x=n*x0/gcd(n1,n2) +k*n2/gcd(a,b)

y=n*y0/gcd(n1,n2)-k*n1/gcd(a,b)

同时要求x>=0,y>=0,我们就可以解得k的范围

k1=ceil(-n*x0/n2)<=k<=floor(n*y0/n1)=k2

若k1>k2,说明也是无解

否则带入T表达式 T=c1*(n*x0/gcd(n1,n2) +k*n2/gcd(a,b))+c2*( n*y0/gcd(n1,n2)-k*n1/gcd(a,b))

整理发现这是一个关于k的一次函数,系数为m=c1*n2-c2*n1,若m>=0,递增,取k1

否则取k2

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main()
{
    ll n;
    ll c1,n1,c2,n2;
    while(scanf("%lld",&n)&&n)
    {
        ll x,y;
        scanf("%lld%lld",&c1,&n1);
        scanf("%lld%lld",&c2,&n2);
        ll g=exgcd(n1,n2,x,y);
        if(n%g) {printf("failed\n");continue;}
        ll x0=x,y0=y;
        x=x*n/g;
        y=y*n/g;
        ll k1=ceil((-n*x0/(double)n2));
        ll k2=floor(n*y0/(double)n1);
        if(k1>k2) {printf("failed\n");continue;}
        ll t=c1*n2-c2*n1;
        ll ans1,ans2;
        if(t>=0)
        {
            ans1=x+k1*n2/g,ans2=y-k1*n1/g;
        }
        else  ans1=x+k2*n2/g,ans2=y-k2*n1/g;
        printf("%lld %lld\n",ans1,ans2);
    }
}
时间: 2024-11-06 03:54:40

UVA10090 数论基础 exgcd的相关文章

数论基础学习总结(持续补充中)

数论基础 算术基本定理(唯一分解定理) 任何一个大于1的自然数都可以唯一分解成有限个素数的乘积 $N=p_1^{a_1}\times p_2^{a_2}\times...\times p_n^{a_n} | p_1<p_2<...<p_n ,a_i\in Z$ 上式中$p_i$为素数 有关素数筛 埃式筛法 就是拿一个已经筛选出的素数去排掉其他的数,比如2是素数,就用他筛掉2*2,2*3,2*4……,3是素数,就用他筛掉3*2,3*3,3*4……,把每个素数的倍数都筛掉,不过我们发现,3*

数论基础总?结?

\(gcd\): inline int gcd(int a,int b){ return b?gcd(b,a%b):a;} 扩展欧几里得:求\(ax+by=gcd(a,b)\)的一组整数解. inline int Exgcd(int a,int b,int &x,int &y) { if(!b) {x=1,y=0;return a;} int Gcd=Exgcd(b,a%b,y,x); y-=a/b*x;return Gcd; } 费马小定理:\(a^{p-1}\equiv 1\mod p

数论基础的补充讲解

数论基础的补充讲解 整除的一些性质: (1)能被2整除的数,个位上的数都能被2整除 (2*)能被4整除的数,个位和十位所组成的两位数能被4整除 (3*)能被8整除的数,百位.十位和个位所组成的三位数能被8整除 (4)能被5整除的数,末尾是0或5 (5*)能被25整除的数,十位和个位所组成的两位数能被25整除 (6*)能被125整除的数,百位.十位和个位所组成的三位数能被125整除 (7)能被3整除的数,各个数位上的数字之和能被3整除 (8*)能被9整除的数,各个数位上的数字和能被 9 整除 (9

数论基础题目八题【欧几里得】【筛法素数】【中国剩余定理】

之前看的数论的知识,现在做几道题目找找感觉..... poj 1061 传送门 题目大意,给你x,y,m,n,L.代表青蛙a的坐标x,青蛙b的坐标y,青蛙a一次跳的距离m,青蛙b一次跳的距离n,以及mod的值L,求经过多少次跳相遇.即求:(m-n)*x0=(x-y)(mod L);  模线性方程的解,不过要注意处理,因为(m-n)和(x-y)有可能是负的,如果(m-n)是负的,则直接对俩数取负数,下面就是对 ((x-y)+L)%L. 然后就能用modular_linear_equation(LL

数论基础的补充解说

数论基础的补充解说 整除的一些性质: (1)能被2整除的数,个位上的数都能被2整除 (2*)能被4整除的数,个位和十位所组成的两位数能被4整除 (3*)能被8整除的数,百位.十位和个位所组成的三位数能被8整除 (4)能被5整除的数.末尾是0或5 (5*)能被25整除的数.十位和个位所组成的两位数能被25整除 (6*)能被125整除的数.百位.十位和个位所组成的三位数能被125整除 (7)能被3整除的数,各个数位上的数字之和能被3整除 (8*)能被9整除的数.各个数位上的数字和能被 9 整除 (9

「数论基础」欧拉定理(费马小定理)

在阅读本篇之前,如果还不熟悉欧拉函数,可以参见另一篇介绍欧拉函数的「数论基础」欧拉函数. 定义:对于互质的两个正整数$a, n$,满足$a^{φ(n)} ≡ 1\  (mod\ n)$ 证明: 设集合$S$包含所有$n$以内与$n$互质的数,共有$φ(n)$个:     $S = \{ x_1, x_2, ..., x_{φ(n)} \} $ 再设集合$T$: $T = \{ a * x_1 \% n, a * x_2 \% n, ..., a * x_{φ(n)} \% n \} $ 由于$

你也可以手绘二维码(二)纠错码字算法:数论基础及伽罗瓦域GF(2^8)

摘要:本文讲解二维码纠错码字生成使用到的数学数论基础知识,伽罗瓦域(Galois Field)GF(2^8),这是手绘二维码填格子理论基础,不想深究可以直接跳过.同时数论基础也是Hash算法,RSA算法等密码学的入门基础. 二维码生成算法最为核心的就是编码规则和纠错码字的生成.本篇专门讲解纠错涉及到的伽罗瓦域(Galois Field).本文内容大部分是阅读<密码编码学与网络安全>后参考相关PPT编写,如有遗漏或不严谨地方请参考专业书籍. 数论基础 整除,因数,素数 设 a , b(b≠0)

kuangbin带你飞---数论基础

又是几天过去,最近在刷数论基础和dp基础.kuangbin数论专题刷了差不多一大半吧.深深感jio到自己的菜.唉,温故而知新,所以决定在踩一遍坑点. Bi-shoe and Phi-shoe https://vjudge.net/problem/LightOJ-1370 题目大意:给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和. 分析:其实用欧拉筛打表欧拉函数值可以发现一个规律,质数的欧拉函数上升增加的速度远比其他数字快,所以此题只用找到第一个大于n的数即

数论基础

听说明天AU爷ysy要给我们讲数论 赶紧预习一下好了 ①高斯消元 嗯这个就不多解释了- 题1 bzoj1013 球形空间产生器 嗯这题就是给你一个n维球体上的n+1个点,求圆心. 所以假设第i个点是(a[i][1],a[i][2]-a[i][n]) 那么我们就是要找一个点(x[1]-x[n])使得 (a[i][1]-x[1])^2+(a[i][2]-x[2])^2+-+(a[i][n]-x[n])^2=r^2 那么我们就有这样n+1个式子: (a[1][1]-x[1])^2+(a[1][2]-x