自己在刷题的过程中难免遇到一些经典算法题,但是刚开始接触的时候,都是奖回溯法解决0-1背包问题。
所以在提交的时候用了回溯法,结果只AC三个点,其他都是超时。但是至少弄懂了回溯法~新手
下面贴一下代码
#include <iostream>
using namespace std;
int s;
int n;
int vmax=-1;
int sum=0;
int vum=0;
void knapsack(int m,int w[],int v[])
{
if(sum>=s||m>=n)
{
if(vum>vmax)
{
vmax=vum;
}
}
else
{
for(int i=0;i<=1;i++)
{
if(i==0)
{
knapsack(m+1,w,v);
}
else if(sum+w[m]<=s)
{
sum+=w[m];
vum+=v[m];
knapsack(m+1,w,v);
sum-=w[m];
vum-=v[m];
}
}
}
}
int main()
{
cin>>s>>n;
int w[n],v[n];
for(int i=0;i<n;i++)
{
cin>>w[i]>>v[i];
}
knapsack(0,w,v);
cout<<vmax<<endl;
return 0;
}
顺便说一下,本人的理解,回溯法就是将模板理解透就好了。贴一下模板:
void backtrack(int t){
if(t 怎么样)
{
output(x);
}
else
for (int i = 0; i <= 1; i++)//这里就是背包的问题的放与不放的代码表现形式,即1为放,0为不放,
//可以自己根据问题改变初值和界值
{
操作;
if(限制条件)
{
backtrack(t+1);
}
每次递归都将上面的操作恢复原样;
}
}