UVA_10465
这个题目可以用初等数学的方法求解,给定m和n,求保证m*x+n*y<=t的条件下x+y的最大值,同时要优先保证m*x+n*y尽可能和t接近。因此x、y可能的取值点就是在m*x+n*y=t这条直线下方且紧邻直线的点,扫描一遍这些点并更新结果即可。
当然这个题目也可以用完全背包来写,同时要注意在所用时间相同的情况下如果个数变大了也要更新一下。
#include<stdio.h>
#include<string.h>
int m, n, T;
void solve()
{
int i, j, x, y, t, num;
x = 0, y = T / n;
t = num = 0;
for(;;)
{
for(;m * x + n * y <= T; x ++)
{
if(m * x + n * y > t)
{
t = m * x + n * y;
num = x + y;
}
else if(m * x + n * y == t)
{
if(x + y > num)
num = x + y;
}
}
if(x > T / m)
break;
for(-- y; m * x + n * y > T; y --);
}
if(t == T)
printf("%d\n", num);
else
printf("%d %d\n", num, T - t);
}
int main()
{
while(scanf("%d%d%d", &m, &n, &T) == 3)
{
solve();
}
return 0;
}
#include<stdio.h>
#include<string.h>
#define MAXD 10010
int a[5], f[MAXD], num[MAXD];
int N, M, T;
void solve()
{
int i, j;
memset(f, 0, sizeof(f));
memset(num, 0, sizeof(num));
for(i = 1; i <= 2; i ++)
for(j = a[i]; j <= T; j ++)
{
if(f[j - a[i]] + a[i] > f[j])
{
f[j] = f[j - a[i]] + a[i];
num[j] = num[j - a[i]] + 1;
}
else if(f[j - a[i]] + a[i] == f[j] && num[j - a[i]] + 1 > num[j])
num[j] = num[j - a[i]] + 1;
}
if(f[T] == T)
printf("%d\n", num[T]);
else
printf("%d %d\n", num[T], T - f[T]);
}
int main()
{
while(scanf("%d%d%d", &a[1], &a[2], &T) == 3)
{
solve();
}
return 0;
}