Tickets HDU - 1260(DP)

本文介绍了一种通过算法优化电影票销售过程的方法,旨在减少顾客购票时间并提高售票效率。文章详细阐述了如何利用动态规划解决售票场景中的时间优化问题,并提供了一个具体的实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 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个人的单独买票时间和K-1个相邻的两个人一起买票的时间,问一共花费的最小时间。用one[i]为每个人单独买票的时间,two[ i+1]为两个人一起买票的时间。
状态转移方程为: dp[i] = min(dp[i-1]+one[i] , dp[i-2] + two[i] )。当前第i个人分为两种情况,一是单独买,而是和前面的一块买。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n,k;
int dp[2050],one[2050],two[2050];
int min(int a,int b)
{
    return a < b ? a : b;
}
int main()
{
    int i;
    scanf("%d",&n);
    while(n--)
    {
       memset(dp,0,sizeof(dp));
       memset(one,0,sizeof(one));
       memset(two,0,sizeof(two));
       scanf("%d",&k);
       for(i=1;i<=k;i++)
       {
         scanf("%d",&one[i]);
       }
       for(i=2;i<=k;i++)
       {
           scanf("%d",&two[i]);
       }
       dp[0] = 0;
       dp[1] = one[1];
       for(i=2;i<=k;i++)
       {
          dp[i] = min(dp[i-1]+one[i],dp[i-2]+two[i]);
       }
       int h = dp[k]/3600 +8;
       int m = dp[k]/60%60;
       int s = dp[k]%60;
       printf("%02d:%02d:%02d am\n",h,m,s);
    }
    return 0;
}
### 题目重述 根据提供的代码文件`112.doc`的要求,以及给出的预期输出结果,我们需要确保在`read committed`隔离级别下,通过主动加锁机制,使事务`t1`能够实现可重复读一致性,并且在事务`t1`结束之后,能够正确反映出事务`t2`对航班MU2455余票数的修改。 ### 给出答案 为了满足上述需求,需要对`t1.sql`和`t2.sql`进行适当的修改,以下是带有注释的答案: #### 修改后的 `t1.sql` ```sql -- 事务1: -- 设置隔离级别为read committed set session transaction isolation level read committed; start transaction; --1次查询航班&#39;MU2455&#39;的余票,并加上共享锁以防止其他事务修改 select tickets from ticket where flight_no = &#39;MU2455&#39; for share; -- 模拟事务2在此期间进行的操作 select pg_sleep(3); -- 第2次查询航班&#39;MU2455&#39;的余票,在加锁情况下,保证数据一致性 select tickets from ticket where flight_no = &#39;MU2455&#39;; commit; -- 等待事务2完成并提交之后,再次查询所有航班的余票情况 select * from ticket order by flight_no; ``` #### 修改后的 `t2.sql` 由于`t2.sql`本身逻辑正确,不需要做任何修改。 ### 代码解析 - **t1.sql** 中的关键改动在于第一次查询语句后面加入了`for share`,这确保了在第一次查询时就对该行数据加上共享锁,阻止了其他事务对该行数据进行更新操作,从而实现了可重复读的效果。 - 使用`select pg_sleep(3);`模拟了事务`2`执行的时间窗口,确保了`事务1`中的两次查询确实跨越了`事务2`的操作时间范围。 - 最终在`事务1`提交后,再次查询所有航班的余票数,这时应该能反映出`事务2`已经成功减少了MU2455航班的余票数。 ### 知识点 - **共享锁与写锁**:共享锁允许多个事务同时读取同一资源,但不允许其他事务对其做修改;写锁则是排他性的,既不允许其他事务读取也不允许修改。 - **事务隔离级别**:`read committed`是最常用的隔离级别之一,它保证了一个事务只能读取已经提交的数据,但是默认情况下无法避免不可重复读的问题。 - **主动加锁机制**:通过SQL语句显式地对数据行或表加锁,可以增强在较低隔离级别下的数据一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值