点击打开链接
其实本题本质上就是一个标准的01背包问题. 问你<=t-1时间内最多可以选择哪些歌曲使得 (数据1,数据2) 最优. 这里的数据1是歌曲数目, 数据2是歌曲总时长, 且数据1优先.
我们令dp[i][j]==x 表示当决策完全前i个物品后(选或不选), 所选的总歌曲时长<=j时, 所得到的最优状态为x. (这里的x就不是平时我们所说的最长时间或最多歌曲数目了)
但是如果用二维数组实现的话,d数组是从上到下,从右往左计算的
sort(v+1,v+n+1);
t--;
memset(d,-1,sizeof(d));
d[0][0]=0;
for(int i=1; i<=n; i++)
{
d[i][0]=0;
for(int j=t; j>=v[i]; j--)
{
d[i][j]=max(d[i-1][j],d[i-1][j-v[i]]+1);
}
}
//cout<
这样就会导致一个问题,例如t=145 v[1]=19,v[2]=133,v[3]=167,v[4]=168,这样计算之后d[2][133]为1,d[3][133]反而成了-1,因为v[3]=167>145 所以第二层循环根本没跑,d[3][133]依旧等于-1
如果改成这样,就没问题了
sort(v+1,v+n+1);
t--;
memset(d,-1,sizeof(d));
d[0][0]=0;
for(int i=1; i<=n; i++)
{
d[i][0]=0;
for(int j=t; j>=0; j--)
{
d[i][j]=d[i-1][j]; //让第i层等于第i-1层
if(j>=v[i])d[i][j]=max(d[i-1][j],d[i-1][j-v[i]]+1);
}
}
sort(v+1,v+n+1);
t--;
memset(d,-1,sizeof(d));
d[0][0]=0;
for(int i=1; i<=n; i++)
{
d[i][0]=0;
for(int j=t; j>=0; j--)
{
d[i][j]=d[i-1][j]; //让第i层等于第i-1层
if(j>=v[i])d[i][j]=max(d[i-1][j],d[i-1][j-v[i]]+1);
}
}
或者利用滚动数组,因为只有一行,所以直接d[i][j]=d[i-1][j]了,不用赋值
#include
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair pii;
const int INF=0x3f3f3f3f;
LL mod=1e9+7;
const int N=1005;
int n,t;
int d[10005]; //在j时间下的最大歌数
int v[55];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
std::ios::sync_with_stdio(false);
std::cin.tie(0);
//int kase=0;
int T;
cin>>T;
int kase=0;
while(T--)
{
cin>>n>>t;
for(int i=1;i<=n;i++)
cin>>v[i];
sort(v+1,v+n+1);
t--;
memset(d,-1,sizeof(d));
d[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=t;j>=v[i];j--)
{
d[j]=max(d[j],d[j-v[i]]+1);
}
}
/*for(int i=1;i<=n;i++)
{
for(int j=v[i];j<=t;j++)
{
cout<=0;i--)
{
if(d[i] > d[ans])
{
ans=i;
}
}
cout<<"Case "<<++kase<<": "<
或者直接用两个dp
#include
#include
int max(int x,int y){
if(x>=y) return x;
else return y;
}
int d[55][10000];
int len[55][10000];
int main(){
int tag,m,n,t,time[55];
scanf("%d",&m);
int count=1;
while(count<=m){
memset(d,0,sizeof(d));
memset(len,0,sizeof(len));
scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++) scanf("%d",&time[i]);
for(int i=n;i>=1;i--){
for(int j=1;j<=t;j++){
d[i][j]=d[i+1][j];
len[i][j]=len[i+1][j];
if(j>time[i]) {
if(d[i][j]