zju 1013
题目大意是说有3种武器,每种都有一个重量w,一个尺寸s,一个战斗系数d,另外,如果把数量分别为c1,c2,c3的3种武器合在一起用,就会得到战斗系数为d4的新武器。
现在,有1,2,3...,n量车子来运输武器,每量车子都有最大运输重量和最大运输尺寸,现在用车量来运输武器,要求出能达到的最大战斗系数。
这题很明显是一道动态规划题,初看题意感觉跟背包问题挺象的,不过那只是表面现象而已。
设f[i][n1][n2]表示用前i量车子在运 n1件1武器和n2件2武器的条件下能运的第3种武器的最大数量。
那么f[0][0][0]=0
设函数num(i,j,k)表示第i量车子在运j个1武器和k个2武器后最多再能运k个3武器,则
f[i][n1][n2]=f[i-1][n3][n4]+num(i,n1-n3,n2-n4)
具体参数的取值范围详见程序。
另外可以看到f[i]的值只于f[i-1]有关,那么可以用滚动数组来节省空间。
算出f[n]后,就可以枚举i,j了,看f[n][i][j]的情况,算出此情况下的战斗系数,这样就可以求出最大值了。
code:
现在,有1,2,3...,n量车子来运输武器,每量车子都有最大运输重量和最大运输尺寸,现在用车量来运输武器,要求出能达到的最大战斗系数。
这题很明显是一道动态规划题,初看题意感觉跟背包问题挺象的,不过那只是表面现象而已。
设f[i][n1][n2]表示用前i量车子在运 n1件1武器和n2件2武器的条件下能运的第3种武器的最大数量。
那么f[0][0][0]=0
设函数num(i,j,k)表示第i量车子在运j个1武器和k个2武器后最多再能运k个3武器,则
f[i][n1][n2]=f[i-1][n3][n4]+num(i,n1-n3,n2-n4)
具体参数的取值范围详见程序。
另外可以看到f[i]的值只于f[i-1]有关,那么可以用滚动数组来节省空间。
算出f[n]后,就可以枚举i,j了,看f[n][i][j]的情况,算出此情况下的战斗系数,这样就可以求出最大值了。
code:
#include <iostream>
#include <string>
using namespace std;
int main( ) {
const int MAXN=501;
int pre[ MAXN ][ MAXN ],now[ MAXN ][ MAXN ];
int w1,s1,d1,w2,s2,d2,w3,s3,d3,c1,c2,c3,d4,n;
int ma,mb;
int cases=0;
while(cin>>n) {
cases++;
if( n==0 ) break;
cin>>w1>>s1>>d1>>w2>>s2>>d2>>w3>>s3>>d3>>c1>>c2>>c3>>d4;
memset( pre,255,sizeof( pre ) );
d4-=c1*d1+c2*d2+c3*d3;
pre[ 0 ][ 0 ]=0;
ma=mb=0;
for( int i=0;i<n;i++ ) {
memset( now,255,sizeof( now ) );
int cw,cs;
cin>>cw>>cs;
int maa=ma,mbb=mb;
for( int i1=0;i1<=maa;i1++ )
for( int j1=0;j1<=mbb;j1++ ) {
if( pre[ i1 ][ j1 ]<0 ) continue;
for( int i11=i1,tw1=0,ts1=0;tw1<=cw&&ts1<=cs;i11++,tw1+=w1,ts1+=s1 )
for( int j11=j1,tw2=tw1,ts2=ts1;tw2<=cw&&ts2<=cs;j11++,tw2+=w2,ts2+=s2 ){
if( ma<i11 ) ma=i11;
if( mb<j11 ) mb=j11;
int da=( cw-tw2 )/w3;
int db=( cs-ts2 )/s3;
if( da>db ) da=db;
if( now[ i11 ][ j11 ]<pre[ i1 ][ j1 ]+da )
now[ i11 ][ j11 ]=pre[ i1 ][ j1 ]+da;
}
}
for( int i11=0;i11<=ma;i11++ )
for( int j11=0;j11<=mb;j11++ )
pre[ i11 ][ j11 ]=now[ i11 ][ j11 ];
}
int max=0;
for( int i=0;i<=ma;i++ )
for( int j=0;j<=mb;j++ ) {
if( now[ i ][ j ]<0 ) continue;
int t=i*d1+j*d2+now[ i ][ j ]*d3;
int a=i/c1;
int b=j/c2;
int c=now[ i ][ j ]/c3;
if( a>b ) a=b;
if( a>c ) a=c;
if( d4>0 ) t+=a*d4;
if( t>max ) max=t;
}
if( cases>1 ) cout<<endl;
cout<<"Case "<<cases<<": "<<max<<endl;
}
return 0;
}
#include <string>
using namespace std;
int main( ) {
const int MAXN=501;
int pre[ MAXN ][ MAXN ],now[ MAXN ][ MAXN ];
int w1,s1,d1,w2,s2,d2,w3,s3,d3,c1,c2,c3,d4,n;
int ma,mb;
int cases=0;
while(cin>>n) {
cases++;
if( n==0 ) break;
cin>>w1>>s1>>d1>>w2>>s2>>d2>>w3>>s3>>d3>>c1>>c2>>c3>>d4;
memset( pre,255,sizeof( pre ) );
d4-=c1*d1+c2*d2+c3*d3;
pre[ 0 ][ 0 ]=0;
ma=mb=0;
for( int i=0;i<n;i++ ) {
memset( now,255,sizeof( now ) );
int cw,cs;
cin>>cw>>cs;
int maa=ma,mbb=mb;
for( int i1=0;i1<=maa;i1++ )
for( int j1=0;j1<=mbb;j1++ ) {
if( pre[ i1 ][ j1 ]<0 ) continue;
for( int i11=i1,tw1=0,ts1=0;tw1<=cw&&ts1<=cs;i11++,tw1+=w1,ts1+=s1 )
for( int j11=j1,tw2=tw1,ts2=ts1;tw2<=cw&&ts2<=cs;j11++,tw2+=w2,ts2+=s2 ){
if( ma<i11 ) ma=i11;
if( mb<j11 ) mb=j11;
int da=( cw-tw2 )/w3;
int db=( cs-ts2 )/s3;
if( da>db ) da=db;
if( now[ i11 ][ j11 ]<pre[ i1 ][ j1 ]+da )
now[ i11 ][ j11 ]=pre[ i1 ][ j1 ]+da;
}
}
for( int i11=0;i11<=ma;i11++ )
for( int j11=0;j11<=mb;j11++ )
pre[ i11 ][ j11 ]=now[ i11 ][ j11 ];
}
int max=0;
for( int i=0;i<=ma;i++ )
for( int j=0;j<=mb;j++ ) {
if( now[ i ][ j ]<0 ) continue;
int t=i*d1+j*d2+now[ i ][ j ]*d3;
int a=i/c1;
int b=j/c2;
int c=now[ i ][ j ]/c3;
if( a>b ) a=b;
if( a>c ) a=c;
if( d4>0 ) t+=a*d4;
if( t>max ) max=t;
}
if( cases>1 ) cout<<endl;
cout<<"Case "<<cases<<": "<<max<<endl;
}
return 0;
}