今晚边吃烤鸡边打练习赛,导致这道简单的dp题没做出来,我辜负了教练,辜负了队友。在此自罚一篇博客。
一、题目
二、分析
v保存该物品的时间,w该物品的价值,t该物品在上面时候毁坏。
定义dp数组:
dp[i]:在前i秒内能能保存的物品最大总和
状态注意方程:
dp[j] = max(dp[j],dp[j-v]+w); j<t且j-v>=0
三、错误过程
WA第一版
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const int M=2010;
int dp[M];
int w[N],v[N],t[N];
int n,m;
int g[N][M];
int cnt;
int q[N],idx;
void dfs(int i,int j)
{
if(i<=0)
return ;
if(g[i][j])
{
cnt++;
q[idx++]=i;
dfs(i-1,j-v[i]);
}
else
dfs(i-1,j);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&v[i],&t[i],&w[i]);
m=max(m,t[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=t[i];j>=v[i];j--)
{
if(dp[j]<dp[j-v[i]]+w[i])
{
dp[j]=dp[j-v[i]]+w[i];
g[i][j]=1;
}
}
}
dfs(n,m);
cout<<dp[m]<<endl;
cout<<cnt<<endl;
for(int i=idx-1;i>=0;i--)
cout<<q[i]<<' ';
return 0;
}
没有考虑第i个物品存在时间小于第i-1的情况,并且读题没发现j<t,而不是j<=t
WA第二版
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const int M=2010;
int dp[M];
int n,m;
int g[N][M];
int cnt;
int q[N],idx;
struct node
{
int id;
int w,v,t;
}e[N];
bool cmp(struct node x1,struct node x2)
{
return x1.t<x2.t;
}
void prin()
{
for(int i=0;i<M;i++)
cout<<dp[i]<<" ";
cout<<endl;
}
void dfs(int i,int j)
{
if(i<=0)
return ;
if(g[i][j])
{
cnt++;
q[idx++]=e[i].id;
dfs(i-1,j-e[i].v);
}
else
dfs(i-1,j);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].v,&e[i].t,&e[i].w);
e[i].id=i;
}
sort(e+1,e+1+n,cmp);
for(int i=1;i<=n;i++)
{
for(int j=e[i].t-1;j>=e[i].v;j--)
{
if(dp[j]<dp[j-e[i].v]+e[i].w)
{
dp[j]=dp[j-e[i].v]+e[i].w;
g[i][j]=1;
}
}
}
dfs(n,e[n].t-1);
cout<<dp[e[n].t-1]<<endl;
cout<<cnt<<endl;
for(int i=idx-1;i>=0;i--)
cout<<q[i]<<' ';
return 0;
}
没有考虑第i个物品存在时间特别长,第i-1存在时间特别短,误认为dp[n][e[n].t-1]一定为答案
四、正确代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const int M=2010;
int dp[M];
int n,m;
int g[N][M];
int cnt;
int q[N],idx;
struct node
{
int id;
int w,v,t;
}e[N];
bool cmp(struct node x1,struct node x2)
{
return x1.t<x2.t;
}
void prin()
{
for(int i=0;i<M;i++)
cout<<dp[i]<<" ";
cout<<endl;
}
void dfs(int i,int j)
{
if(i<=0)
return ;
if(g[i][j])
{
cnt++;
q[idx++]=e[i].id;
dfs(i-1,j-e[i].v);
}
else
dfs(i-1,j);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].v,&e[i].t,&e[i].w);
e[i].id=i;
}
sort(e+1,e+1+n,cmp);
int x,y,Max=0;
for(int i=1;i<=n;i++)
{
for(int j=e[i].t-1;j>=e[i].v;j--)
{
if(dp[j]<dp[j-e[i].v]+e[i].w)
{
dp[j]=dp[j-e[i].v]+e[i].w;
g[i][j]=1;
}
if(Max<dp[j])
{
Max=dp[j];
x=i,y=j;
}
}
}
dfs(x,y);
cout<<Max<<endl;
cout<<cnt<<endl;
for(int i=idx-1;i>=0;i--)
cout<<q[i]<<' ';
return 0;
}