uVa 12563 Jin Ge Jin Qu

  分析可知,虽然t<109,但是总曲目时间大于t,实际上t不会超过180*n+678.此问题涉及到两个目标信息,首先要求曲目数量最多,在此基础上要求所唱的时间尽量长。可以定义

状态dp[i][j]表示前i首歌曲,恰好唱的时间为j时,所唱的最长时间,于是就是裸的01背包了。

/*----UVa12563 Jin Ge Jin Qu
*/
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<string.h>
#include<math.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 50 + 10;

int dp[maxn*180+678]; //dp[i][j]表示前i首歌曲,时间长度恰好为j,所唱的最多曲数,可以直接使用一维数组
int t[maxn];

int main(){
	int i, j,T,iCase=1,n,m;
	scanf("%d", &T);
	while (T--){
		scanf("%d%d", &n, &m);
		m--;   //在此不能恰好唱完,因为后面还要唱一首jin Ge Jin Qu
		for (i = 1; i <= n; i++)scanf("%d", &t[i]);

		for (i = 0; i <= m; i++)dp[i] = -INF;
		dp[0] = 0;

		for (i = 1; i <= n; i++){
			for (j = m;j>=t[i];j--)
             dp[j]=max(dp[j], dp[j - t[i]] + 1);
		}
		int ans =-INF, maxt = -INF;
		for (j = m; j >=0; j--)
			if (ans < dp[j]){ ans = dp[j];maxt = j;}
		
		printf("Case %d: %d %d
",iCase++,ans + 1, maxt + 678);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/td15980891505/p/5786513.html