题目
天啊,多好的电影啊!成千上万的人涌向电影院。然而,对于卖电影票的乔来说,这真的是一个艰难的时刻。他在徘徊,什么时候能早点回家。
一个减少售票总时间的好办法是让相邻的人一起买票。由于售票机的限制,乔可以一次卖出一张票或两张相邻的票。
因为你是伟大的耶稣,你确切地知道每个人为他/她买一张或两张票需要多少时间。你能告诉可怜的乔他什么时候能早点回家吗?如果是这样,我想乔会对你的帮助充满感激。
简单说就是卖票,可以一张一张卖,也可以两张两张卖,问你卖完需要的最小时间?
题解
求卖完一定数量的票所需的最小时间?
卖到第n张票的时候,他可以由两种状态转移过来,一种是第从n-1张票转移过来,就是单独卖第n张票;另一种是从第n-2张票转移过来,就是连着卖两张票,这两种状态取最小值,dp[i]表示卖第i张票所需的最短时间
状态转移方程:
dp[i] = min(dp[i - 1] + time[i], dp[i - 2] + both[i]);
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iomanip>
using namespace std;
const int MAXN=2*1e3+100;
int num[MAXN];
int adj[MAXN];
int dp[MAXN];
int main(){
int t;
cin>>t;
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
for(int i=2;i<=n;i++){
scanf("%d",&adj[i]);
}
dp[1]=num[1];
dp[2]=min(dp[1]+num[2],adj[2]);
for(int i=3;i<=n;i++){
dp[i]=min(dp[i-1]+num[i],dp[i-2]+adj[i]);
}
int hour=8,minn=0,sec=0;
hour+=dp[n]/3600;
dp[n]=dp[n]%3600;
minn+=dp[n]/60;
dp[n]=dp[n]%60;
sec+=dp[n];
if(hour>12)
cout<<setw(2)<<setfill('0')<<hour-12<<":"<<setw(2)<<setfill('0')<<minn<<":"<<setw(2)<<setfill('0')<<sec<<" pm"<<endl;
else
cout<<setw(2)<<setfill('0')<<hour<<":"<<setw(2)<<setfill('0')<<minn<<":"<<setw(2)<<setfill('0')<<sec<<" am"<<endl;
}
return 0;
}