ZOJ 1918 Ferry Loading II

設f(i,j)表示第i次運輸能將第j輛車運到對岸,抵達時所花的最小時間。

f(i,j)=f(i-1,j-k)+回岸的時間T+T。當然,若回岸時車還未到達,f(i,j)=j車抵達的時間+T。

 

#include <cstdio>
#include 
<string>

#define min( x, y ) ( x < y ? x : y )
#define max( x, y ) ( x > y ? x : y )

int T, N, M, CS;
int t[1500];
int b[2][1500];    // 第n次渡過m人最小時間,滾存

void init ()
{
    scanf ( 
"%d%d%d"&N, &T, &M );
    
int i;
    
for ( i = 1; i <= M; i ++ )
        scanf ( 
"%d"&t[i] );
}


void dp ()
{
    
int i, j, k, p;
    
int minTime = 1 << 30, minStep, step;
    memset ( b, 
64sizeof ( b ) );
    
for ( j = 1, p = 0, step = 1; j <= N; j ++ )
    
{
        b[p][j] 
= T + t[j];
        
if ( j == M && b[p][j] < minTime )
            minTime 
= b[p][j], minStep = step;
    }

    
//pt ( p );
    for ( i = 2, p = 1 - p, step ++; i <= M; i ++, p = 1 - p, step ++ )
    
{
        memset ( b[p], 
64sizeof ( b[p] ) );
        
for ( j = i; j <= min ( M, i * N ); j ++ )
        
{
            
for ( k = 1; k <= N; k ++ )
                b[p][j] 
= min ( b[p][j], max ( b[1 - p][j - k] + T, t[j] ) + T );
            
if ( j == M && b[p][j] < minTime )
                minTime 
= b[p][j], minStep = step;
        }

        
//pt ( p );
    }

    printf ( 
"%d %d ", minTime, minStep );
}


int main ()
{
    
//freopen ( "in.txt", "r", stdin );
    
//freopen ( "out.txt", "w", stdout );
    scanf ( "%d"&CS );
    
int i;
    
for ( i = 0; i < CS; i ++ )
    
{
        init ();
        dp ();
    }

    
return 0;
}

發佈了56 篇原創文章 · 獲贊 0 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章