题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1260

Tickets

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

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
 
Source
 
 
题解:
 
 
原始做法:
1.dp[i][j][status]表示:第i个人属于第j个组合,他的状态是status(是跟前一个人组队还是自己买)的最少花费时间。
2.状态转移方程:
dp[i][j][] = dp[i-][j][] - a[i-] + b[i-];  //跟上一个人组队
dp[i][j][] = min(dp[i-][j-][], dp[i-][j-][]) + a[i]; //自己买
 
代码如下:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 2e3+; int dp[MAXN][MAXN][], a[MAXN], b[MAXN]; int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i<=n; i++) scanf("%d", &a[i]);
for(int i = ; i<n; i++) scanf("%d", &b[i]); for(int i = ; i<=n; i++)
for(int j = ; j<=n; j++)
dp[i][j][] = dp[i][j][] = INF/; dp[][][] = ;
for(int i = ; i<=n; i++)
for(int j = (i+)/; j<=i; j++) //最少应该属于第(i+1)/2个组合
{
dp[i][j][] = dp[i-][j][] - a[i-] + b[i-]; //跟上一个人组队
dp[i][j][] = min(dp[i-][j-][], dp[i-][j-][]) + a[i]; //自己买
} int time = INF;
for(int i = (n+)/; i<=n; i++)
time = min(time, min(dp[n][i][], dp[n][i][]) ); int second = time%;
int minute = (time/)%;
int hour = time/ + ; int id = ;
if(hour>){
id = ;
hour = hour-;
}
printf("%02d:%02d:%02d %s\n", hour, minute, second, id?"pm":"am");
}
}
 
 
改进:
1.后来发现规划第i个人属于第几个集合时多余的,所以: dp[i][status]表示:第i个人的状态是status的最少花费时间。
2.状态转移方程:
dp[i][] = dp[i-][] - a[i-] + b[i-];    //跟上一个人组队
dp[i][] = min(dp[i-][], dp[i-][]) + a[i]; //自己买
代码如下:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 2e3+; int dp[MAXN][], a[MAXN], b[MAXN]; int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i<=n; i++) scanf("%d", &a[i]);
for(int i = ; i<n; i++) scanf("%d", &b[i]); for(int i = ; i<=n; i++)
dp[i][] = dp[i][] = INF/; dp[][] = ;
for(int i = ; i<=n; i++)
{
dp[i][] = dp[i-][] - a[i-] + b[i-];
dp[i][] = min(dp[i-][], dp[i-][]) + a[i];
}
int time = min(dp[n][], dp[n][]); int second = time%;
int minute = (time/)%;
int hour = time/ + ; int id = ;
if(hour>){
id = ;
hour = hour-;
}
printf("%02d:%02d:%02d %s\n", hour, minute, second, id?"pm":"am");
}
}
 
 
再改进:
1.再后来发现,前面两份代码都要用status来标记第i个人是否自己买,但是实际可以不用标记:如果第i个人自己买, 那么可以直接:dp[i] = dp[i-1] + a[i],如果跟别人组队买,那么 dp[i] = dp[i-2] + b[i-1],直接跳到前两个,免去了考虑前一个是否自己买。
2.状态转移方程:
dp[i] = min(dp[i-]+a[i], dp[i-]+b[i-]);
  
代码如下:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 2e3+; int dp[MAXN], a[MAXN], b[MAXN]; int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i<=n; i++) scanf("%d", &a[i]);
for(int i = ; i<n; i++) scanf("%d", &b[i]); dp[] = ; dp[] = a[];
for(int i = ; i<=n; i++)
dp[i] = min(dp[i-]+a[i], dp[i-]+b[i-]); int second = dp[n]%;
int minute = (dp[n]/)%;
int hour = dp[n]/ + ; int id = ;
if(hour>){
id = ;
hour = hour-;
}
printf("%02d:%02d:%02d %s\n", hour, minute, second, id?"pm":"am");
}
}

HDU1260 Tickets —— DP的更多相关文章

  1. kuangbin专题十二 HDU1260 Tickets (dp)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  2. HDU-1260.Tickets(简单线性DP)

    本题大意:排队排票,每个人只能自己单独购买或者和后面的人一起购买,给出k个人单独购买和合买所花费的时间,让你计算出k个人总共花费的时间,然后再稍作处理就可得到答案,具体格式看题意. 本题思路:简单dp ...

  3. HDU1260(KB12-H DP)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  4. hdu1260(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1260 分析:简单dp,dp[i]=min(dp[i-1]+a[i],dp[i-2]); #includ ...

  5. H - Tickets dp

    题目链接: https://cn.vjudge.net/contest/68966#problem/H AC代码; #include<iostream> #include<strin ...

  6. HDU 1260 Tickets DP

    http://acm.hdu.edu.cn/showproblem.php?pid=1260 用dp[i]表示处理到第i个的时候用时最短. 那么每一个新的i,有两个选择,第一个就是自己不和前面的组队, ...

  7. 「kuangbin带你飞」专题十二 基础DP

    layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...

  8. 【HDU - 1260 】Tickets (简单dp)

    Tickets 搬中文 Descriptions: 现在有n个人要买电影票,如果知道每个人单独买票花费的时间,还有和前一个人一起买花费的时间,问最少花多长时间可以全部买完票. Input 给出 N(1 ...

  9. HDU 1260 Tickets(简单dp)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

随机推荐

  1. ArrayList练习之存储自定义对象并遍历

    新建一个Student.java类 Student.java /* * 这是一个学生类 */ public class Student { private String name; private i ...

  2. HDU1757-A Simple Math Problem,矩阵快速幂,构造矩阵水过

    A Simple Math Problem 一个矩阵快速幂水题,关键在于如何构造矩阵.做过一些很裸的矩阵快速幂,比如斐波那契的变形,这个题就类似那种构造.比赛的时候手残把矩阵相乘的一个j写成了i,调试 ...

  3. Go切片基础

    package main import "fmt" //切片(Slice)本身没有数据,是对底层Array的一个view //不使用指针就可以改数组内容 //slice可以向后扩展 ...

  4. shell脚本简单密码加密

    #!/bin/sh #输入密码 echo "请输入原密码:" read resultFirst firstPWD=$resultFirst echo "请再次输入原密码: ...

  5. 博弈 Nim问题 POJ2234

    定义: 通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是 “选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了, 则判负(因为他此刻 ...

  6. [Vijos] 弱弱的战壕

    描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒 ...

  7. webmagic使用手册

    https://my.oschina.net/flashsword/blog/180623 重点 SeleniumDownloader 对于一些Javascript动态加载的网页,仅仅使用http模拟 ...

  8. Intersecting Lines--POJ1269(判断两条直线的关系 && 求两条直线的交点)

    http://poj.org/problem?id=1269 我今天才知道原来标准的浮点输出用%.2f   并不是%.2lf  所以wa了好几次 题目大意:   就给你两个线段 然后求这两个线段所在的 ...

  9. Java面试题总结(一)---Java基础

    Java面试题总结(一)---Java基础 1.面向对象的特征有哪些? 答:面向对象的特征主要有以下几个: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方 ...

  10. 【c++】c++一些基础面试题

    http://www.mianwww.com/html/2013/10/19128.html http://blog.csdn.net/wdzxl198/article/details/9050751 ...