题目描述
Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this is really a tuff time for Joe who sells the film tickets. He is wandering when could he go back home as early as possible.
A good approach, reducing the total time of tickets selling, is let adjacent people buy tickets together. As the restriction of the Ticket Seller Machine, Joe can sell a single ticket or two adjacent tickets at a time.
Since you are the great JESUS, you know exactly how much time needed for every person to buy a single ticket or two tickets for him/her. Could you so kind to tell poor Joe at what time could he go back home as early as possible? If so, I guess Joe would full of appreciation for your help.
Input
There are N(1<=N<=10) different scenarios, each scenario consists of 3 lines:
1) An integer K(1<=K<=2000) representing the total number of people;
2) K integer numbers(0s<=Si<=25s) representing the time consumed to buy a ticket for each person;
3) (K-1) integer numbers(0s<=Di<=50s) representing the time needed for two adjacent people to buy two tickets together.
Output
For every scenario, please tell Joe at what time could he go back home as early as possible. Every day Joe started his work at 08:00:00 am. The format of time is HH:MM:SS am|pm.
Sample Input
2
2
20 25
40
1
8
Sample Output
08:00:40 am
08:00:08 am
这道题大意如下:K个人窗口排队买票,票可以一张一张卖,也可以挨着的两个人连在一起卖。现在给定卖给每个人一张票的时间,和同时卖给相邻两人票的时间。求卖票所用时间最短是多少。
解题思路
这道题一看到,我就联想到了最长上升子序列。我们只要维护状态矩阵dp,dp[i]代表,当第i个人是最后一个人的时候,卖票所用时间的最短值。第i个人有两种买票的方式,自己单独买,和前一个人一块儿买。那么dp[i]就可以由dp[i-1]和dp[i-2]两个状态转移而来。状态转移公式如下
dp[i]=max(dp[i?1]+S[i],dp[i?2]+D[i?1])dp[i] = max(dp[i-1]+S[i],dp[i-2]+D[i-1]) dp[i]=max(dp[i?1]+S[i],dp[i?2]+D[i?1])
其中S[i]是第i个人单独卖票所用的钱,D[i-1]代表第i-1和第i个人一起买票所用时间
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
// cout<<78%60;
// int max_time = 15200;
// int time_s = max_time%60;
// int time_m = (max_time/60)%60;
// int time_h = (max_time/60)/60;
// cout<<time_s<<endl<<time_m<<endl<<time_h;int N,K;int i,j;int S[2005],D[2005];//int dps[2005],dpm[2005];int dp[2005];cin>>N;while(N--){
cin>>K;for(i = 0;i<K;i++) cin>>S[i];for(i = 0;i<K-1;i++) cin>>D[i];if(K==1){
int min_time = S[0];int time_s = min_time%60;int time_m = (min_time/60)%60;int time_h = (min_time/60)/60;if(time_h<=4) printf("%02d:%02d:%02d am\n",time_h+8,time_m,time_s);elseprintf("%02d:%02d:%02d pm\n",time_h+8,time_m,time_s);continue;}
// dps[0] = S[0];
// dps[1] = S[0]+S[1];
// dpm[1] = D[0];dp[0] = S[0];dp[1] = min(S[0]+S[1],D[0]);for(i = 2;i<K;i++){
dp[i] = min(dp[i-1]+S[i],dp[i-2]+D[i-1]);
// dpm[i] = dps[i-1]-S[i-1]+D[i-1];
// dps[i] = min(dps[i-1],dpm[i-1])+S[i];}
// int min_time = min(dpm[K-1],dps[K-1]);int min_time = dp[K-1];int time_s = min_time%60;int time_m = (min_time/60)%60;int time_h = (min_time/60)/60;if(time_h<=4) printf("%02d:%02d:%02d am\n",time_h+8,time_m,time_s);elseprintf("%02d:%02d:%02d pm\n",time_h+8,time_m,time_s);// cout<<time_s<<endl<<time_m<<endl<<time_h<<endl;}
}