#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 1e9
using namespace std;
int dp[30][110][110];
// dp[i][j][k]:第i頭奶牛領跑,共跑了j圈,共消耗能量k,的最少時間
int main() {
int N, E, D;
while(cin>>N>>E>>D) {
for(int i = 0; i <= N; ++i) {
for(int j = 0; j <= D; ++j)
for(int k = 0; k <= E; ++k)
dp[i][j][k] = inf;
}
dp[1][0][0] = 0; // 初始條件
for(int i = 1; i <= N; ++i) {
for(int j = 0; j <= D; ++j) {
for(int k = 0; k <= E; ++k) {
// 枚舉i、j、k,當dp[i][j][k]有意義時,進行狀態轉移
if(dp[i][j][k] == inf) continue;
for(int l = 1; l + j <= D && l*l + k <= E; ++l)
// 枚舉奶牛以每分鐘跑l圈的速度,注意總圈數和初始能量的限制即可
dp[i][j+l][k+l*l] = min(dp[i][j+l][k+l*l], dp[i][j][k] + 1);
// 這裏還有一個重要的轉移! 當前奶牛退出比賽輪到下一頭奶牛領跑。
// 注意能量變化,下頭奶牛已經跑了j圈,初始能量消耗也應該爲j
dp[i+1][j][j] = min(dp[i+1][j][j], dp[i][j][k]);
}
}
}
// 找出跑完N圈的最少時間,如果跑不完dp[N][D][0] = 0,不需特判
int Min = inf;
for(int i = 0; i <= E; ++i)
Min = min(Min, dp[N][D][i]);
cout<<Min<<endl;
}
return 0;
}
POJ 1946(三維DP)
http://poj.org/problem?id=1946
題意:有N頭奶牛,要跑D圈,每頭奶牛的初始能量爲E,每頭牛每分鐘可以跑任意圈,除領跑的奶牛外,每跑x圈,消耗能量爲x,領跑的奶牛消耗的能量爲x*x,能量消耗盡的奶牛隨時退場,問至少有一頭奶牛能去到終點所用的最短時間。
思路:dp[i][j][k]表示前i-1頭奶牛都已耗盡能量或者中途離場,現在第i頭奶牛已經跑了j圈且已經消耗了k的能量,假設,當前奶牛繼續以l圈/分鐘的速度跑一分鐘,則狀態dp[i][j+l][k+l*l] = dp[i][j][k] + 1,(j+l <= D,j+l*l <= E),當然,狀態是否轉移,要判斷轉移後所消耗時間是否更小。其次,每頭奶牛可以在任何時候隨時退場,輪到下一頭奶牛領跑,所以還有一個特別點的轉移方式,dp[i+1][j][j] = dp[i][j][k],主要理解的是能量的變化,因爲第i+1頭奶牛剛剛領跑,之前一共跟跑了j圈,所以已經消耗的能量是j,而且換領隊是不需要消耗時間的,當然是否轉移也是要判斷一下大小的,詳見代碼。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.