uva 12563

#include<cstring>
#include<iostream>
#include<algorithm>
#include<climits>
#define local
using namespace std;
int ci;
int T;
int n;
int t;
int a[100];
int dp[12000];
int main()
{
#ifdef local
	freopen("C:\\Users\\sukieandxuan\\Desktop\\新建文件夹\\data.in", "r", stdin);
	freopen("C:\\Users\\sukieandxuan\\Desktop\\新建文件夹\\data.out", "w", stdout);
#endif
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d %d", &n, &t);
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &a[i]);
		}
		memset(dp, -1, sizeof(dp));
		a[n] = 678;
		dp[0] = 0;
		//printf("%d", minute);
		for (int i = 0; i <= n; i++)
		{
			for (int j = t-1+a[i]; j >=a[i] ; j--)
			{
				if (dp[j-a[i]] != -1)
				{
					dp[j] = max(dp[j], dp[j-a[i]] + 1);
					printf("%d %d\n", dp[j], j);
				}
			}
		}
		int max1 = INT_MIN, ans = 0;
		for (int i = 10000; i >= 0; i--)
		{
			if (dp[i] != -1)
			{
				if (max1 < dp[i])
				{
					max1 = dp[i];
					ans = i;
				}
				
			}
		}
		printf("Case %d: %d %d\n", ++ci, max1, ans);
	}
	return 0;
}

先贴代码。(ps:代码看起来长其实真正用到的很短233)
这道题一开始我以为就是简单的背包问题,结果发现读题不仔细,他要求时间最长我求出来时间最短。
思路:

利用滚动数组,假设从t+a[i]开始遍历,j-a[i]的值就可以从0- t-1取值,即满足小于t-1的要求。这里的dp为唱歌的歌曲数目,dp的下标为时间数。因为这里我把678也加入到了数组中,所以即便是之前例如 40 80 ,加起来为120超过了100,最后的40 80 678,也会选择40+678,因为不会遍历到120,而且歌曲数目也正好 40 80为2,40 80 678 也为2 。

最后说一说我这道题挂了10次,我一直觉得我算法没有问题,仔细一看发现我的t是用lld输入的,因为一开始以为t<=10^9,后来发现t<=9000,就不需要担心了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值