ZOJ-1524

31 篇文章 0 订阅

又是DP,没有想像那么简单。。开始天真地直接硬搞,连sample的数据都过不了。。后来改了改算法,把最优解的最大商品下标保存下来,下次取的商品不能和前面最优结构最大下标相同,简单数据可以过,但是真实数据非常大,有几组数据这样是过不了。。算法有问题,后来仔细研究了一组数据,发现了存在的问题,尝试反向遍历DP,竟然过了。。原理的理解不是很透彻,多刷些DP加深理解吧。。网上搜了搜其他人的代码,感觉自己的应该是最简洁的了,时间和空间都不大,小得瑟一下

#include<stdio.h>
#include<limits.h>

int main()
{
	int m, n, a[101];
	double dp[101];
	while (scanf("%d %d", &m, &n), m || n)
	{
		int i, j, k;
		double p;
		for (i = 1; i <= m; i++)
		{
			scanf("%d", &a[i]);
			dp[i] = INT_MAX;
		}
		dp[0] = 0;
		for (j = 1; j <= n; j++)
		{
			scanf("%d %lf", &k, &p);
			//注意一定要从反向遍历,正向遍历就WA
			for (i = m; i > 0; i--)
				if (a[i] == k && dp[i - 1] != INT_MAX && dp[i - 1] + p < dp[i])
					dp[i] = dp[i - 1] + p;
		}
		if (dp[m] != INT_MAX)
			printf("%.2lf\n", dp[m]);
		else
			puts("Impossible");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值