標籤:dp
跑跑卡丁車
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2514 Accepted Submission(s): 875
Problem Description跑跑卡丁車是時下一款流行的網路休閒遊戲,你可以在這虛擬世界裡體驗駕駛的樂趣。這款遊戲的特別之處是你可以通過漂移來獲得一種
加速卡,用這種加速卡可以在有限的時間裡提高你的速度。為了使問題簡單化,我們假設一個賽道分為L段,並且給你通過每段賽道的普通耗時Ai和用加速卡的耗時Bi。加速卡的獲得機制是:普通行駛的情況下,每通過1段賽道,可以獲得20%的能量(N2O).能量集滿後獲得一個加速卡(同時能量清0).加速卡最多可以儲存2個,也就是說當你有2個加速卡而能量再次集滿,那麼能量清零但得不到加速卡。一個加速卡只能維持一段賽道,遊戲開始時沒有加速卡。
問題是,跑完n圈最少用時為多少?
Input每組輸入資料有3行,第一行有2個整數L(0<L<100),N(0<N<100)分別表示一圈賽道分為L段和有N圈賽道,接下來兩行分別有L個整數Ai和Bi
(Ai > Bi).
Output對於每組輸入資料,輸出一個整數表示最少的用時.
Sample Input
18 19 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 98 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 8 8
Sample Output
145HintHint 對於sample這組資料,你可以先在普通情況下行駛前14段,這時你有2個加速卡以及80%的能量(N2O).在第15和16段用掉2個加速卡,通過第17段賽道後又可以得到一個加速卡,在第18段賽道使用.
一道dp題目。
注釋裡是第一次打的代碼,用了二維來選項組。
後來看了題解,就把time 一維 用來 做滾動數組。 然後把20%NO記做1。一張卡 記做5。這樣只用一維,比較簡單。
按要求寫出狀態方程。加速的時候time[cur][k]=min(time[cur][k],time[cur^1][k+5]+b[j]); 不加速的時候 time[cur][k]=min(time[cur][k],time[cur^1][k-1]+a[j]);
注意,如果兩張卡,而且有80%的NO的時候 再積累NO, 那麼不會多得到一張卡片。 time[cur][10]=min(time[cur][10],time[cur^1][14]+a[j]);
#include <stdio.h> #include <iostream>#include <algorithm>#include <cmath>#include <map>#include <string>using namespace std;int time[2][20]; //一維滾動數組 int a[110],b[110];int main(){int L,n;while(scanf("%d%d",&L,&n)!=EOF){for(int i=0;i<=14;i++){ time[0][i]=99999999; }time[0][0]=0;for(int i=0;i<L;i++)cin>>a[i];for(int i=0;i<L;i++)cin>>b[i]; int cur=0; for(int i=0;i<n;i++){for(int j=0;j<L;j++){cur^=1;for(int k=0;k<=14;k++)time[cur][k]=99999999;/*for(int k=0;k<=14;k++){if(k%5==0)puts("");printf("%9d",time[cur^1][k]); }puts("\n");*/for(int k=0;k<=14;k++){//加速 bif(k<=9)time[cur][k]=min(time[cur][k],time[cur^1][k+5]+b[j]); //普通 aif(k!=0)time[cur][k]=min(time[cur][k],time[cur^1][k-1]+a[j]); //if(k==10)//time[cur][10]=min(time[cur][10],time[cur^1][14]+a[j]);}}} int minn=99999999;for(int i=0;i<=14;i++)minn=min(minn,time[cur][i]);printf("%d\n",minn);}return 0;}/*int time[2][5][10];//一維滾動數組 二維記錄有幾張卡 三維記錄當前有多少NOint a[110],b[110];//耗時間int main(){int L,n;while(scanf("%d%d",&L,&n)!=EOF){for(int i=0;i<3;i++){for(int j=0;j<5;j++){time[0][i][j]=99999999;}}time[0][0][0]=0;for(int i=0;i<L;i++){scanf("%d",a+i);}for(int i=0;i<L;i++){scanf("%d",b+i);}int cur=0;for(int i=0;i<n;i++)//quan{for(int j=0;j<L;j++)//duan{cur^=1;//當前的for(int k=0;k<3;k++){for(int l=0;l<5;l++){ //printf("%8d ",time[cur^1][k][l]);time[cur][k][l]=99999999;}//puts("");}//puts("");//用卡加速的情況 //bfor(int k=0;k<2;k++){for(int l=0;l<5;l++){time[cur][k][l]=min(time[cur][k][l],time[cur^1][k+1][l]+b[j]); }}//不用卡的情況 //afor(int k=0;k<3;k++){for(int l=0;l<5;l++){if(l!=0)//增加 NOtime[cur][k][l]=min(time[cur][k][l],time[cur^1][k][l-1]+a[j]); else if(k!=0)//{time[cur][k][l]=min(time[cur][k][l],time[cur^1][k-1][4]+a[j]);//增加卡片 if(k==2)//卡片 超過2 不增加卡片time[cur][k][l]=min(time[cur][k][l],time[cur^1][k][4]+a[j]);}}}}}int ans=99999999;for(int k=0;k<3;k++){for(int l=0;l<5;l++){ans=min(ans,time[cur][k][l]);}}printf("%d\n",ans); }return 0;}*//*18 19 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 98 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 8 8*/
hdu 1494 跑跑卡丁車 dp