Tickets HDU - 1260 dp

本文介绍了一种优化购票策略的算法,通过动态规划方法计算出在特定条件下,一群人购票的最短时间。算法考虑了单独购票和集体购票两种情况,旨在找到最佳购票方案,减少等待时间。

标题

d[0][i]表示第i个人没和前面的人一起买票 前i个人的最小时间
d[1][i]表示第i个人和前面的人一起买票 前i个人的最小时间
第i个人如果选择和前面的人一起则只能通过d[i - 1][0]转移过来
如果不和前面的人一起可以选择d[i - 1][0]和d[i - 1][1]取min转移过来

AC代码

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int MAXN = 2e3 + 10;
int a[MAXN], b[MAXN];
int d[2][MAXN]; //是否两人 前i人的最小花费

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
    int T;
    cin >> T;
    while (T--)
    {
        int h = 8, m = 0, s = 0;
        memset(d, 0x3f, sizeof(d));
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        for (int i = 2; i <= n; i++)
            scanf("%d", &b[i]);
        d[1][0] = 0;
        for (int i = 1; i <= n; i++)
        {
            d[0][i] = min(d[0][i - 1], d[1][i - 1]) + a[i];
            d[1][i] = d[0][i - 1] - a[i - 1] + b[i];
        }
        int ans = min(d[0][n], d[1][n]);
        s += ans % 60, ans /= 60;
        m += ans % 60, ans /= 60;
        h += ans % 12, ans /= 12;
        if (ans && !h)
            printf("12:%02d:%02d pm\n", m, s);
        else
            printf("%02d:%02d:%02d %s\n", h, m, s, ans ? "pm" : "am");
    }

	return 0;
}
在Java中,表达式 `tickets-- <= 0` 的行为涉及两个关键操作:**比较**和**自增/自减操作**。理解其执行顺序和逻辑是掌握该表达式行为的关键。 ### 运算顺序 Java中的运算顺序遵循操作符优先级和结合性规则。在表达式 `tickets-- <= 0` 中,涉及两个操作符: - `--`(后缀自减) - `<=`(小于等于) 其中,`--`的优先级高于 `<=`,因此 `tickets--` 会先执行,但**后缀自减操作的返回值是自减前的值**。随后,该值被用于与 `0` 进行比较。 具体执行过程如下: 1. **获取 `tickets` 的当前值**,作为比较的左操作数。 2. **执行 `tickets--`**,即对 `tickets` 的值进行自减操作。 3. **将第一步获取的值与 `0` 进行比较**,判断是否满足 `<= 0` 的条件。 例如,假设 `tickets` 的初始值为 `1`,则执行过程如下: - 获取 `tickets` 的当前值 `1`。 - 执行 `tickets--`,`tickets` 的值变为 `0`。 - 使用获取的值 `1` 与 `0` 进行比较,即 `1 <= 0`,结果为 `false`。 如果 `tickets` 的值为 `0`,则执行过程如下: - 获取 `tickets` 的当前值 `0`。 - 执行 `tickets--`,`tickets` 的值变为 `-1`。 - 使用获取的值 `0` 与 `0` 进行比较,即 `0 <= 0`,结果为 `true`。 因此,`tickets-- <= 0` 的条件判断结果取决于 `tickets` 的初始值,而不是自减后的值[^1]。 ### 条件判断逻辑 在多线程环境下,`tickets-- <= 0` 的逻辑可能引发线程安全问题。例如,在以下代码中: ```java class RunDemo implements Runnable { int tickets = 1; @Override public void run() { while (true) { System.out.println("卖出了第" + tickets + "票"); if (tickets-- <= 0) { break; } } } } ``` 多个线程共享同一个 `RunDemo` 实例时,`tickets--` 的操作不是原子的,可能导致多个线程同时读取相同的 `tickets` 值,并执行自减操作,从而引发**数据竞争**。最终可能导致条件判断的错误,例如 `tickets` 的值变为负数,或者循环提前终止[^2]。 为了避免此类问题,可以采用同步机制,例如使用 `synchronized` 关键字或 `Lock` 接口,确保每次只有一个线程能够执行 `tickets--` 操作。例如: ```java class RunDemo implements Runnable { private int tickets = 1; private final Object lock = new Object(); @Override public void run() { while (true) { synchronized (lock) { if (tickets <= 0) { break; } System.out.println("卖出了第" + tickets + "票"); tickets--; } } } } ``` 通过这种方式,可以确保 `tickets--` 和条件判断在同步块中执行,从而避免线程安全问题[^3]。 ### 相关问题 1. Java中后缀自增/自减操作的返回值是什么? 2. 如何在多线程环境下确保共享变量操作的原子性? 3. 使用 `synchronized` 和 `ReentrantLock` 有什么区别? 4. 多线程编程中如何避免条件判断的竞态条件?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值