HDU - 1260 Tickets (dp + 贪心)

Tickets

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12145    Accepted Submission(s): 5993

Problem Description

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 个人要买票,对应的第 i 个人需要花费 a[ i ] 的时间,但是每个人可以和他前面的一个人一起买票(显然第一个人不行,只能从第二人开始),对应的需要花费 b[ i ]的时间。(b [ 1 ] 直接设为 inf )

思路:考虑使用二维 dp[ i ][ j ], i 表示的是第几个人,j 只有两个状态 0 和 1,分别表示前一个人一起买表, 不与前面一个人一起买票。状态转移方程就出来了:

dp[ i ] [ 0 ] = min( dp[i - 1][ 0 ], dp[ i - 1][ 1 ]) + a[ i ] ; //第 i 个人未与第 i - 1 个人一起买票,只需第 i - 1 个人两个状态的最小值

dp[ i ][ 1 ] = dp[i - 1][ 0 ] + b[ i ] - a[ i - 1 ] ; //第 i 个人与第 i - 1 个人一起买票,所以第 i - 1 个人就不能与第 i - 2个人一起买票                                                              //了,既然一起买票了,第 i - 1个人就不需要花费原本a[ i - 1 ]的时间,所以要减去a[ i - 1 ]

最后答案就是: min(dp[ n ][ 0 ], dp[ n ][ 1 ])

//#include <bits/stdc++.h>
#include <map>
//#include <tr1/unordered_map>
#include<limits>
#include <float.h>
#include <list>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int lowbit(int x){ return x & (-x); }
inline int read(){int X = 0, w = 0; char ch = 0;while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
    while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();return w ? -X : X;}
inline int gcd(int a, int b){ return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x)
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define db double
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e6 + 10;
const int maxp = 1e3 + 10;
const LL INF = 0x3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = 20090717;

int n, take, a[2010], b[2010], dp[2010][2];

int main(){
    b[1] = inf;
    int t = read();
    while (t--){
        Sca(n);
        For (i, 1, n) a[i] = read();
        For (i, 2, n) b[i] = read();
        For (i, 1, n){
            dp[i][0] = min(dp[i-1][0],dp[i-1][1]) + a[i];
            dp[i][1] = dp[i-1][0] + b[i] - a[i-1];
        }
        take = min(dp[n][0], dp[n][1]);
        int h = 8, m = 0, s = 0;
        h = (h + take / 3600) % 24; m = (take % 3600) / 60; s = take % 60;
        if (h > 12) printf("%02d:%02d:%02d pm\n", h - 12, m, s);
        else printf("%02d:%02d:%02d am\n", h, m, s);
    }

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值