UVA10465

题目的意思就是一个人吃面包 .

有两种面包.第一种吃一个要m分钟 ,第二种吃一个要n分钟.

然后你有 t 分钟的时间来吃..

你要在时间最接近 t  的情况下,吃最多个.

如果刚好为 t  输出吃的个数.( 输出 为一个)

如果是在没办法刚好, 那就输出在时间最接近 t 时吃最多多少个,并且输出剩下的时间, (输出为 两个);

我们用两个数组来做 dp ;

第一个是f[ i ] .表示你吃东西时间为i 你最多用掉多少时间.

第二个是d[ i ] 表示你吃东西时间为i 你最多吃掉几个面包.


我们首先要维护f[ i ] 为最大.

然后在f [ i ]最大的情况下 ,维护d [ i ] 最大.

做题思路是先假设只有第一种面包可以吃,算出f[ i ] ,d[ i ].

然后在加上第二种面包

通过比较 以及 状态转移

if (i >= n && f[i - n]  + n > f[i]) {
				f[i] = f[i - n] + n;
				d[i] = d[i - n] + 1;
			}
			if (i >= n && f[i - n] + n == f[i]) {
				d[i] = d[i] > d[i - n] + 1 ? d[i] : d[i - n] + 1;
			}

来更新最优值 (其实就是判断 这时候是保持原样 ,吃第一种好 ,还是改吃第二种好 ).


AC代码:


#include<stdio.h>
#include<string.h>
const int N = 10005;
int m,n,t;
int f[N];
int d[N];
int main () {
	while(~scanf("%d%d%d",&m,&n,&t)) {
		memset(f, 0 ,sizeof(f));
		memset(d, 0 ,sizeof(d));
		for (int i = 1 ; i <= t ; i++) {
			f[i] = f[i - 1];
			if (i >= m) {
				f[i] = f[i - m] + m;
				d[i] = d[i - m]  + 1;
			}
		}
		for (int i = 1 ; i <= t ;i++) {
			if (i >= n && f[i - n]  + n > f[i]) {
				f[i] = f[i - n] + n;
				d[i] = d[i - n] + 1;
			}
			if (i >= n && f[i - n] + n == f[i]) {
				d[i] = d[i] > d[i - n] + 1 ? d[i] : d[i - n] + 1;
			}
		}
		printf("%d",d[t]);
		if(f[t] != t) 
			printf(" %d",t - f[t]);
		printf("\n");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值