题目地址:点击打开链接
题意:求在给定时间内,最多能唱多少歌曲,在歌曲最多的情况下,使唱的时间最长,时间到时如果当前歌还没结束,那会等该歌结束。
思路:类似01背包,歌曲时长作为重量,价值都为1,求t-1内最多能放多少歌,在歌曲最多的情况下再更新最后一首歌最晚能什么时候结束。不同于01背包的时,这里要求每首歌连续播放,所以在决策时要加一个条件,这首歌正好在这个时间点播放完。
参考:点击打开链接
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e2+5;
int ti[maxn], dp[50*200+678];
int main(void)
{
int T, t, n, ca = 1;
cin >> T;
while(T--)
{
scanf("%d%d", &n, &t);
for(int i = 1; i <= n; i++)
scanf("%d", &ti[i]);
int maxNum = 0, maxTime = 0;
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
for(int j = t-1; j-ti[i] >= 0; j--)
{
if(j == ti[i] || dp[j-ti[i]]) //要求正好能放完
{
dp[j] = max(dp[j], dp[j-ti[i]]+1);
if(dp[j] > maxNum) maxNum = dp[j], maxTime = j;
if(dp[j] == maxNum) maxTime = max(j, maxTime);
}
}
printf("Case %d: %d %d\n", ca++, maxNum+1, maxTime+678);
}
return 0;
}
本文介绍了一种改进的01背包问题解决方案,应用于歌曲播放列表的最大化问题。通过调整决策条件,确保歌曲连续播放的同时,实现播放时间和歌曲数量的最大化。
647

被折叠的 条评论
为什么被折叠?



