#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,而且换领队是不需要消耗时间的,当然是否转移也是要判断一下大小的,详见代码。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.