普通写法:
普通的我就不详细解释了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n,vol;
struct spe
{
int value,vol;
};
spe p[1005];
int dp[1005];
int main()
{
int T;
scanf("%d",&T);
while( T-- )
{
scanf("%d %d",&n,&vol);
for( int i = 1 ; i <= n; i++ )
{
scanf("%d",&p[i].value);
}
for( int i = 1 ; i <= n; i++ )
{
scanf("%d",&p[i].vol);
}
memset(dp,0,sizeof dp);
for( int i = 1 ; i <= n ; i++ )
{
for( int j = vol ; j >= p[i].vol ; j-- )
{
dp[j] = max( dp[j],dp[j-p[i].vol]+p[i].value );
}
}
cout<<dp[vol]<<endl;
}
return 0;
}
/*
1 2
1 7
1 3
1 4
1 9
3
*/
第二种写法:
当然,它也有它的使用范围拉,当价值的范围很小的时候才能用这个,而且用这个算法,它的复杂度和背包容量没有关系,所以说我们是根据价值来写的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
ll dp[10000005];
ll val[105],v[105];
ll T,n,m;
int main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
int sum = 0;
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&v[i],&val[i]);
sum += val[i];
}
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[0] = 0; //一定不能省略
for(int i=0;i<n;i++)
for(int j=sum;j>=val[i];j--)
dp[j] = min(dp[j], dp[j - val[i]] + v[i]);
// int ans = -1;
for(int i=sum;i>=0;i--)
{
if(dp[i] <= m)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}