UVa 10465 - Homer Simpson

Contents

  1. 1. Problem
  2. 2. Solution
  3. 3. Code

Problem

題目網址
中文網址

時間內看辛普森最多可以吃多少個漢堡,如果無法把時間用盡,也要使啤酒的數量盡可能的少。

Solution

可以直接用算的,比 DP 快。先盡可能吃花費時間較小的漢堡,再減少它的數量來看是否可加入第二種漢堡,並使得剩餘時間更少(也就是啤酒數較少)。

另一種就是用 DP 湊每個時間可吃的漢堡數,再從剩餘時間找出可以使啤酒數最少的。

Code

UVa 10465(1)UVa 10465 - Homer Simpson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

#include<cstdio>

inline int input();
int main()
{
int a, b, t;
while ((a = input()) != EOF)
{
b = input();
t = input();

//小的先
if (a > b)
{
int temp = a;
a = b;
b = temp;
}

int time = t;
int eat = t / a;//吃 a 漢堡的數量
t %= a;//吃完 a 後所剩餘的時間

if (t)
{
//減少 a 的數量來湊 b
for (int i = eat; i >= 0; i--)//由上往下做,在時間利用完的情況下漢堡數為最多
{
int remain = time - i*a;//目前剩下的時間
if (!(remain % b))//可以把時間利用完
{
eat = i + remain / b;
t = 0;
break;
}

//判斷此時吃掉 b 漢堡後的剩餘時間是否更少
if (remain % b < t)
{
t = remain % b;
eat = i + remain / b;
}
}
}

if (t)
printf("%d %d\n", eat, t);
else
printf("%d\n", eat);
}

return 0;
}
int input()
{
int n = 0;
char c;
while ((c = getchar()) != ' '&&c != '\n')
{
if (c == EOF)
return -1;
n = n * 10 + c - '0';
}
return n;
}

DP

UVa 10465(2)UVa 10465 - Homer Simpson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include<cstdio>

int main()
{
int burger[2], eat[10000], t;

while (scanf("%d%d%d", &burger[0], &burger[1], &t) != EOF)
{
int i, j;
eat[0] = 0;
for (i = 1; i <= t; i++)
eat[i] = -1;

//-1 為無法湊得的,eat 表該時間可吃的漢堡數
for (i = 0; i < 2; i++)
for (j = burger[i]; j <= t; j++)
{
if (eat[j - burger[i]] != -1)
if (eat[j - burger[i]] + 1 > eat[j])
eat[j] = eat[j - burger[i]] + 1;
}

//eat 的 index 代表時間,所以從上往下做,如果沒辦法完全消耗完時間,就會選最接近。
for (i = t; i >= 0; i--)
if (eat[i] != -1)
{
printf("%d", eat[i]);
break;
}

if (i != t)
printf(" %d", t - i);

putchar('\n');
}

return 0;
}