题目描述
Zexal的偶像SkyLee趁着假期来逛漫展,漫展只有一条通道,只能从入口进入,出口离开,且左边有n个店铺,右边也有n个店铺,编号都是1~n。为了照顾大家没法兼顾逛两边的痛苦,左边和右边编号相同的店铺卖同样的周边。
现在SkyLee站在入口处的路中间,立志要从头到尾按顺序逛完所有的店铺。
因为每家店铺排队的人数不同,SkyLee在左边第i家要停留 p1[i] 的时间,在右边第i家要停留 p2[i] 的时间。而且这条路还挺宽的,所以从左边第i家移动到右边第i+1家需要t[1][i]的时间;从右边第i家移动到左边第i+1家需要t[2][i]的时间。
由于时间安排的紧,SkyLee想知道逛完漫展至少需要多长时间。
开始时从路中间到任意一边的时间以及同一边相邻店铺移动时间忽略不计。
输入
多组数据输入
对于每一组测试数据,第一行1个数 n (0<=n<=500)表示店铺数 。
接下来一行 n 个数,表示在左边店铺停留时间 p1。再接下来一行nn个数,表示在右边店铺停留时间 p2(0<=p1,p2<=1000)。
接下来2行,每行n−1个数,分别表示 t[1][i]和 t[2][i] (0<=t<=300)。
输出
对于每组数据,输出一行,为最少时间TT。
输入样例
3 10 1 10 8 5 10 3 1 1 3
输出样例
20
Hint
算法导论第二版15.1节
转移方程
dp[i][1] = min(dp[i-1][1], dp[i-1][0] + t[i-1][0]) + a[i][1];
dp[i][0] = min(dp[i-1][0], dp[i-1][1] + t[i-1][1]) + a[i][0];
代码
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int n,dp[1005][2],a[1005][2],t[1005][2]; int main() { while(~scanf("%d",&n)) { memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) scanf("%d",&a[i][0]); for(int i = 1; i <= n; i++) scanf("%d",&a[i][1]); for(int i = 1; i < n; i++) scanf("%d",&t[i][0]); for(int i = 1; i < n; i++) scanf("%d",&t[i][1]); for(int i = 1; i <= n; i++) { dp[i][1] = min(dp[i-1][1], dp[i-1][0] + t[i-1][0]) + a[i][1]; dp[i][0] = min(dp[i-1][0], dp[i-1][1] + t[i-1][1]) + a[i][0]; } printf("%d ",min(dp[n][1], dp[n][0])); } return 0; }