標籤:io os ar for sp div art on c
題目:110米欄,運動員能夠用三種狀態跑,1狀態耗體力且跑得快,2狀態不消耗體力,3狀態恢複體力且跑得慢。
體力上限是M,且初始滿體力,如今想知到最小的時間跑全然程。
分析:dp,全然背包。題目是一個物品體積可能為負數的背包,求背包就可以。
只是,由於物品體積可能是負數,所以無論哪個方向背包都有後效性,直接用二維避免後效性。
轉移方程:F(i,j)= min(F(i-F1,j)+ T1,F(i-1,j)+ T2,F(i+F2,j)+T3)。
說明:(2011-09-19 01:23)。
#include <iostream>#include <cstdlib>using namespace std;int F[ 111 ][ 111 ];int T1[ 111 ];int T2[ 111 ];int T3[ 111 ];int F1[ 111 ];int F2[ 111 ];int dp( int N, int M ){ for ( int i = 0 ; i <= N ; ++ i ) for ( int j = 0 ; j <= M ; ++ j ) F[ i ][ j ] = 0xffffff; for ( int i = 0 ; i <= M ; ++ i ) F[ 0 ][ i ] = 0; for ( int i = 1 ; i <= N ; ++ i ) { /* 第一狀態 */ for ( int j = F1[ i ] ; j <= M ; ++ j ) if ( j <= M && F[ i ][ j-F1[ i ] ] > F[ i-1 ][ j ] + T1[ i ] ) F[ i ][ j-F1[ i ] ] = F[ i-1 ][ j ] + T1[ i ]; /* 第二狀態 */ for ( int j = 0 ; j <= M ; ++ j ) if ( F[ i ][ j ] > F[ i-1 ][ j ] + T2[ i ] ) F[ i ][ j ] = F[ i-1 ][ j ] + T2[ i ]; /* 第三狀態 */ for ( int j = 0 ; j <= M ; ++ j ) if ( F[ i ][ min(j+F2[ i ],M) ] > F[ i-1 ][ j ] + T3[ i ] ) F[ i ][ min(j+F2[ i ],M) ] = F[ i-1 ][ j ] + T3[ i ]; } int Min = 0xffffff; for ( int i = 0 ; i <= M ; ++ i ) if ( Min > F[ N ][ i ] ) Min = F[ N ][ i ]; return Min;}int main(){ int T,N,M; while ( cin >> T ) while ( T -- ) { cin >> N >> M; for ( int i = 1 ; i <= N ; ++ i ) cin >> T1[ i ] >> T2[ i ] >> T3[ i ] >> F1[ i ] >> F2[ i ]; cout << dp( N, M ) << endl; } return 0;}
zoj 2972 - Hurdles of 110m