题意:一个渡河问题,船每次最多可以载n辆车,单程渡河的时间是t,有m辆车要渡河,问最少时间把所有车运过河去的时间是多少,这个情况下,最少的运输次数是多少。

分析:确实是动态规划,惭愧我想了很久,也没想出状态转移方程,主要是因为我一直想把过河时间和次数放在一起表示状态,其实,过河时间做状态就行了,也必须只用过河时间做状态,因为要求的是过河时间的最小值。

dp[i]表示第i辆车通过河的最小时间, trip[i]运送第i两车过河的总运输次数

状态转移方程:

    dp[i] = min{ max(dp[j]+t, time[i]) + t)}, i-n <= j < i

    trip[i] = trip[j] + 1, j为最小的那个

代码:

 

代码
#include<cstdio>
#include
<cstring>
#include
<iostream>
using namespace std;
#define MY_MAX 1500

int main(){
// freopen("in", "r", stdin);
int dp[MY_MAX], trip[MY_MAX], time[MY_MAX];
int case_num, i, j, n, t, m;
scanf(
"%d", &case_num);
while(case_num--){
memset(dp,
0xFF, sizeof(dp));
memset(trip,
0, sizeof(trip));

scanf(
"%d %d %d", &n, &t, &m);
for(i=1; i<=m; ++i)
scanf(
"%d", &time[i]);
dp[
0] = -t;
dp[
1] = time[1] + t;
trip[
1] = 1;
for(i=2; i<=m; ++i){
for(j=max(0, i-n); j<i; ++j){
int tmp = max(dp[j]+t, time[i]) + t;
if(dp[i] == -1){
dp[i]
= tmp;
trip[i]
= trip[j] + 1;
continue;
}
if(tmp < dp[i]){
dp[i]
= tmp;
trip[i]
= trip[j] + 1;
}
else if(tmp == dp[i] && trip[j] + 1 < trip[j])
trip[i]
= trip[j] + 1;
}
}
printf(
"%d %d\n", dp[m], trip[m]);
}
return 0;
}

 

 

posted on 2010-08-01 08:19  yongmou-  阅读(1186)  评论(0编辑  收藏  举报