0-1背包问题
想了很久终于想明白这个很多人都说简单的0-1背包问题···还得感谢小鸣·····
#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1010][1010];//这么大的数组还是在主函数外面开,搞到第一次直接崩溃。
int w[1010],v[1010];//w代表重量,v代表价值。
int main( )
{
int T,i,j,k,l;
int N,W;
int MAX;//最大值
while(cin>>T)
{
for(i=1;i<=T;++i)
{
cin>>N>>W;
for(k=1;k<=N;++k)
cin>>v[k];
for(k=1;k<=N;++k)
cin>>w[k];
memset(a, 0, sizeof(a));//初始化,因为没有初始化,WA了两次,不是第一次了。
MAX=0;
for(j=1;j<=N;++j)
{
for(l=0;l<=W;++l)//l要从零开始因为有可能背包不能转东西,因为这个又WA了一次。
{
if(l>=w[j])
a[j][l]=max(a[j-1][l],a[j-1][l-w[j]]+v[j]);
else
a[j][l]=a[j-1][l];
//这个状态转移方程搞了很久才明白,有时候有点古板,还是多看看数学的东西令思维好点。
MAX=max(MAX,a[j][l]);
}
}
cout<<MAX<<endl;
}
}
return 0;
}
简单数塔问题;
从底到上:
#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[110][110];//不知道为什么,居然会在主函数外开数组,可能是做0-1背包问题时候崩溃怕了···
int main( )
{
int T,i;
int N,j,k,l;
while(cin>>T)
{
for(i=1;i<=T;++i)
{
cin>>N;
memset(a,0,sizeof(a));//初始化。
for(j=1;j<=N;++j)
for(k=1;k<=j;++k)//不知道为什么在想的时候明明是跟自己说要注意每一行输入的数据的数目跟行数一样
//谁知道敲代码时敲错了,还以为自己又理解错了那个状态转移方程。
cin>>a[j][k];
for(j=N;j>=1;--j)
for(k=1;k<=j;++k)
{
a[j][k]=max(a[j+1][k],a[j+1][k+1])+a[j][k];//状态转移方程,核心,不过这个很简单,个人觉得比0-1背包那个简单多了。
}
cout<<a[1][1]<<endl;
//这个是从底到上的方法,还有从上到底的方法。所以输出的是最顶头的数字。
}
}
return 0;
}
随便把从上到底的代码也敲了出来·····不过没注释·····
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int a[110][110];
int main( )
{
int T,i;
int N,j,k,l;
int MAX;
while(cin>>T)
{
for(i=1;i<=T;++i)
{
cin>>N;
memset(a,0,sizeof(a));
for(j=1;j<=N;++j)
for(k=1;k<=j;++k)
cin>>a[j][k];
for(j=2;j<=N;++j)
for(k=1;k<=j;++k)
{
a[j][k]=max(a[j-1][k-1],a[j-1][k])+a[j][k];
}
MAX=0;
for(l=1;l<=N;++l)
{
if(a[N][l]>MAX)
MAX=a[N][l];
}
cout<<MAX<<endl;
}
}
return 0;
}
如果有那位大神看了这篇文章不要吐槽····小弟不容易····动态规划还有很多很多很多东西看····还是继续努力吧·····