Sicily 4836. Class Schedule

2012年每週一賽第一場第五題,原本想着有機會做出來的,想了個dp算法,但複雜度是O(CT2),覺得不太可能,就放棄去打DotA了。第二天一早試了下,居然是可以過的……

首先,假設dp[i][j]表示第i目錄下的第j課所需要的最小能量,那麼狀態轉移方程就是dp[i][j]=min(dp[i-1][k]+abs(P[i-1][k]-P[i][j])+E[i][j]),理解爲從第i-1目錄下的第k課到當前課的最小能量中的最小值,其中1<=k<=T。最後再找出dp[C][j]到離開的最小值輸出即可。

Run Time: 0.03sec

Run Memory: 480KB

Code Length: 1185Bytes

SubmitTime: 2012-02-26 11:28:21

// Problem#: 4836
// Submission#: 1220391
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
using namespace std;

inline int abs( int n ) { return n < 0 ? -n: n; }
inline int min( int a, int b ) { return a < b ? a: b; }

int main()
{
    int Z, C, T, L;
    int P[ 26 ][ 1001 ], E[ 26 ][ 1001 ];
    int dp[ 26 ][ 1001 ], result;
    int i, j, k;

    scanf( "%d", &Z );
    while ( Z-- ) {
        scanf( "%d%d%d", &C, &T, &L );
        for ( i = 1; i <= C; i++ ) {
            for ( j = 1; j <= T; j++ )
                scanf( "%d%d", &P[ i ][ j ], &E[ i ][ j ] );
        }

        for ( j = 1; j <= T; j++ )
            dp[ 1 ][ j ] = P[ 1 ][ j ] + E[ 1 ][ j ];
        for ( i = 2; i <= C; i++ ) {
            for ( j = 1; j <= T; j++ ) {
                dp[ i ][ j ] = dp[ i - 1 ][ 1 ] + abs( P[ i - 1 ][ 1 ] - P[ i ][ j ] ) + E[ i ][ j ];
                for ( k = 2; k <= T; k++ )
                    dp[ i ][ j ] = min( dp[ i ][ j ], dp[ i - 1 ][ k ] + abs( P[ i - 1 ][ k ] - P[ i ][ j ] ) + E[ i ][ j ] );
            }
        }

        result = dp[ C ][ 1 ] + ( L - P[ C ][ 1 ] );
        for ( j = 2; j <= T; j++ )
            result = min( result, dp[ C ][ j ] + ( L - P[ C ][ j ] ) );
        printf( "%d\n", result );
    }

    return 0;

}                                 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章