Jin Ge Jin Qu hao

在这里插入图片描述
UVA12563
定义:dp[i][j]为考虑前i首歌并且总时长为j时最多能唱的歌曲数,Song[i]表示第i首歌的时长。
转移方程
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − S o n g [ i ] ] + 1 ) dp[i][j]=max(dp[i-1][j],dp[i-1][j-Song[i]]+1) dp[i][j]=max(dp[i1][j],dp[i1][jSong[i]]+1)
经典的01背包。
题目特殊要求在注释中说明。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;
int n, T;
int Song[51], dp[51][10001];
void Input() {
	cin >> n >> T;
	for (int i = 1; i <= n; ++i) {
		cin >> Song[i];
	}
}
void DP() {
	memset(dp, 0x8f, sizeof(dp));
	for (int i = 0; i <= n; ++i) {
		dp[i][0] = 0;
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j < Song[i]; ++j) {
			dp[i][j] = dp[i - 1][j];
		}
		for (int j = Song[i]; j <= T; ++j) {
			dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - Song[i]] + 1);
		}
	}
}
void Output(const int&Case) {
//枚举dp[n][j],找出最多的歌曲数,由于要留1秒给《劲歌金曲》,所以从T-1开始枚举。
//由于要逗留最长时间,所以时间从大到小枚举,知道遇到第一个歌曲数对应的时间点
	int Ans = T - 1;
	for (int j = T - 1; j >= 0; j--) {
		if (dp[n][j] > dp[n][Ans]) {
			Ans = j;
		}
	}
	printf("Case %d: %d %d\n", Case, dp[n][Ans] + 1, Ans + 678);
}
int main() {
	int T;
	cin >> T;
	for (int Case = 1; Case <= T; ++Case) {
		Input();
		DP();
		Output(Case);
	}
	return 0;
}

PS:可以优化成一维数组,但是嘛,怎么方便怎么来233333

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值