题目:http://www.tyvj.cn/p/1005
dp解法01:
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
//f[i]的意思是i时间能获得最大价值
int f[1005],t[105],w[105];
int T,n;
int main()
{
scanf("%d %d",&T,&n); //数据输入
for(int i=1;i<=n;i++)
{
scanf("%d %d",&t[i],&w[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=T;j>=0;j--)
{
if(j+t[i]<=T)
{
f[j+t[i]]=max(f[j+t[i]],f[j]+w[i]); //仔细想这行代码,类似分成j,t[i]两部分
}
}
}
printf("%d\n",f[T]);
return 0;
} dp解法02:#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int T,M;
int t[105],v[105];
int m[105][1005]; //m[i][j]的意思是:当背包容量为j,从第i个背包开始能装下的最大价值(i>=1)
int x[105]; //保存最优解
void beibao()
{
for(int i=0;i<t[M];i++) //处理最后一行前一部分
m[M][i]=0;
for(int i=t[M];i<=T;i++)//处理最后一行后一部分
m[M][i]=v[M];
for(int i=M-1;i>=1;i--) //处理M-1~1行
{
for(int j=0;j<t[i];j++)
m[i][j]=m[i+1][j]+0; //装不下第i个背包
for(int j=t[i];j<=T;j++)
m[i][j]=max(m[i+1][j-t[i]]+v[i],m[i+1][j]+0);//装的下第i个背包,可以选择装或者不装
}
/*
做一点优化 先处理M-1~2行,再处理第一行(因为第一行不用全部都填表)
for(int i=M-1;i>=2;i--) //处理M-1~2行
{
for(int j=0;j<t[i];j++)
m[i][j]=m[i+1][j]+0; //装不下第i个背包
for(int j=t[i];j<=T;j++)
m[i][j]=max(m[i+1][j-t[i]]+v[i],m[i+1][j]+0);//装的下第i个背包,可以选择装或者不装
}
m[1][T]=m[2][T]; //处理第一行
if(T>t[1])
m[1][T]=max(m[2][T-t[1]]+v[1],m[2][T]+0);
*/
}
void Traceback()
{
for(int i=1;i<=M-1;i++)
{
if(m[i][T]==m[i+1][T])
x[i]=0;
else
x[i]=1,T-=t[i];
}
x[M]=(m[M][T])?1:0;
}
int main()
{
scanf("%d %d",&T,&M);
for(int i=1;i<=M;i++)
scanf("%d %d",&t[i],&v[i]);
beibao();
printf("%d\n",m[1][T]);
/*
输出最优解
Traceback();
for(int i=1;i<=M;i++)
printf("%d,",x[i]);
return 0;
*/
} dp解法03:
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
int F[1005];
int t[105],v[105];
int T,M;
int main()
{
scanf("%d %d",&T,&M);
for(int i=1;i<=M;i++)
scanf("%d %d",&t[i],&v[i]);
for(int i=1;i<=M;i++)
{
for(int k=T;k>=t[i];k--)
{
F[k]=max(F[k],F[k-t[i]]+v[i]);
}
}
cout<<F[T]<<endl;
return 0;
}
本文提供了三种不同的动态规划解决背包问题的方法。通过示例代码详细解释了每种解法的思路与实现细节,帮助读者理解如何高效地求解背包问题。
837

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



