题意
有N条船,每条船过河需要20S,桥放下和拉起需要60S,要求使得桥放下之后的总时间最小,问这个最小的总时间
题解
想清楚了就发现很简单。。。
状态转移方程如下:dp[i]代表前i条船通过所需要的最少时间
dp[i]=min(dp[i],dp[i-j]+max(a[i]-a[i-j+1]+20-1800,j*20)+120);
对于一条船,这条船有可能是在前面某一条船把桥拉起的时候,没有放下,然后通过可以得到最小值。因此暴力去枚举究竟会在哪一条船把桥拉起之后没有放下去,而是等待这条船通过再拉起就可以了。
代码
#include<bits/stdc++.h>
#define UP(i,l,h) for(int i=l;i<h;i++)
#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)
#define W(t) while(t)
#define MEM(a,b) memset(a,b,sizeof(a))
#define LL long long
#define INF 0x3f3f3f3f
#define EPS 1e-6
#define MAXN 1010
#define MOD 100000007
#define COUT(x) cout<<x<<endl
#define PI acos(-1)
using namespace std;
int a[4010];
int dp[4010];
int main(){
int n;
scanf("%d",&n);
MEM(a,0);
UP(i,1,n+1){
scanf("%d",&a[i]);
}
MEM(dp,0);
UP(i,1,n+1){
dp[i]=INF;
UP(j,1,i+1){
dp[i]=min(dp[i],dp[i-j]+max(a[i]-a[i-j+1]+20-1800,j*20)+120);
}
}
printf("%d\n",dp[n]);
}