http://47.93.249.116/problem.php?id=2169
有两个壶分别为a,b升,(使a>b)以及一个桶c升。
打水一次有三个模式,分别为用a壶打一次,用b壶打一次,用a-b打一次(即a打水倒入b所剩余a-b),
1.这三种模式,是无限次的 ,我们就可以当做完全背包来理解。
2.可得等式ax+by=c或者ax+(a-b)y=c满足这两个等式才有解。 典型的扩展欧几里得。
题目就转化为求上面两个方程式的x+y的最小解,不过注意x>=0&&y>=0。
3.1e7直接暴力解决不超时
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<vector> #include<math.h> #include<string> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 10000009 int dp[N]; int main() { int e,f,g; while(scanf("%d%d%d",&e,&f,&g)!=EOF) { for(int i=1;i<=g;i++) dp[i]=INF;
dp[0]=0; for(int i=e;i<=g;i++) dp[i]=min(dp[i],dp[i-e]+1); for(int i=f;i<=g;i++) dp[i]=min(dp[i],dp[i-f]+1); if(e!=f) { for(int i=abs(e-f);i<=g;i++) dp[i]=min(dp[i],dp[i-abs(e-f)]+1); } if(dp[g]>=INF) { printf("No\n"); continue; } printf("Yes %d\n",dp[g]); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<vector> #include<math.h> #include<string> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 10000009 LL minn; LL exgcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1; y=0; return a; } else { LL g=exgcd(b,a%b,x,y); LL t=x; x=y; y=t-a/b*y; return g; } } void prime(int a,int b,int c) { LL x,y; LL g=exgcd(a,b,x,y); if(c%g!=0) return ; LL t=ceil(-1.0*c*x/b); if(c*y/g-a*t/g<0) return ; minn=min(minn,c*x/g+c*y/g-a*t/g+b*t/g); return ; } int main() { LL a,b,c; while(scanf("%lld%lld%lld",&a,&b,&c)!=EOF) { minn=INF; if(a<b) swap(a,b); prime(b,a,c); prime(a-b,a,c); if(minn==INF) printf("No\n"); else printf("Yes %d\n",minn); } return 0; }
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<math.h> #include<vector> #include<map> #include<numeric> using namespace std; #define LL long long #define INF 0x3f3f3f3f #define N 1006 int main() { int a,b,c; while(scanf("%d%d%d",&a,&b,&c)!=EOF) { if(a<b) swap(a,b); int minn=INF; for(int i=0;i<=c/a;i++) { int d=c-i*a; if(d%b==0) minn=min(minn,i+d/b); if(a!=b&&d%(a-b)==0) minn=min(minn,i+d/(a-b)); } if(minn==INF) printf("No\n"); else printf("Yes %d\n",minn); } return 0; }