题目
题解思路
因为状态方程 相同 ,我们只需要让每种背包符合它自己的要求转移即可
给出两种优化多重的代码
都优化为一维了
AC代码
使用单调队列优化多重
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
int f[1010] , g[1010] , q[1010] ;
int main ()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for (int i = 1 ; i <= n ; i++ )
{
int v,w,s;
cin>>v>>w>>s;
if (s == 0 )
{
for (int j = v ; j <= m ; j++ )
{
f[j] = max(f[j] , f[ j-v ] + w ) ;
}
}else if ( s != -1 )
{
memcpy( g , f , sizeof ( g ) );
for (int j = 0 ; j < v ; j++ )
{
int hh = 0 , tt = -1 ;
for (int k = j ; k <= m ; k += v )
{
if ( hh <= tt && q[hh] < k - v*s )
hh++;
while( hh <= tt && g[q[tt]] + (k - q[tt])/v*w <= g[k] )
tt--;
tt++;
q[tt] = k ;
f[k] = g[q[hh]] + (k - q[hh] )/v*w;
}
}
}else
{
for (int j = m ; j >= v ; j-- )
{
f[j] = max(f[j] , f[ j-v ] + w ) ;
}
}
}
cout<<f[m]<<"\n";
return 0 ;
}
使用二进制优化多重
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
int f[1010];
int main ()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for (int i = 1 ; i <= n ; i++ )
{
int v,w,s;
cin>>v>>w>>s;
if (s == 0 )
{
for (int j = v ; j <= m ; j++ )
{
f[j] = max(f[j] , f[ j-v ] + w ) ;
}
}else if ( s != -1 )
{
int j ;
for ( j = 1 ; j <= s ; j*=2 )
{
for ( int k = m ; k >= j*v ; k-- )
{
f[k] = max( f[k] , f[ k-j*v ] + j*w ) ;
}
}
if ( j != s )
{
j = s - j/2 ;
for ( int k = m ; k >= j*v ; k-- )
{
f[k] = max( f[k] , f[ k-j*v ] + j*w ) ;
}
}
}else
{
for (int j = m ; j >= v ; j-- )
{
f[j] = max(f[j] , f[ j-v ] + w ) ;
}
}
}
cout<<f[m]<<"\n";
return 0 ;
}