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:
#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;
    
forint i=0;i<n;i++ ) {
        memset( now,
255,sizeof( now ) );
        
int cw,cs;
        cin
>>cw>>cs;
        
int maa=ma,mbb=mb;
        
forint i1=0;i1<=maa;i1++ )
        
forint j1=0;j1<=mbb;j1++ ) {
            
if( pre[ i1 ][ j1 ]<0 ) continue;
            
forint i11=i1,tw1=0,ts1=0;tw1<=cw&&ts1<=cs;i11++,tw1+=w1,ts1+=s1 )
            
forint 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;
            }
            
        }
        
forint i11=0;i11<=ma;i11++ )
        
forint j11=0;j11<=mb;j11++ )
            pre[ i11 ][ j11 ]
=now[ i11 ][ j11 ];   
    }
    
int max=0;
    
forint i=0;i<=ma;i++ )
        
forint 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;
}


posted on 2007-07-19 00:20  woodfish  阅读(903)  评论(0编辑  收藏  举报

导航