m0_65509689 2023-04-01 16:28 采纳率: 80%
浏览 21
已结题

帮帮我,感激不尽。赏关注

有 n 个人在排队取餐。每个人都有自己的口味偏好,他们会在手机上自助选择好自己想要的餐品。不同的餐品需要不同的制作时间。

你是这家餐厅的老板,作为生意火爆的网红打卡点,你的餐厅营业时间一天只有m分钟。如果某个顾客能够吃到他点的餐品,他会就给餐厅打分。第i个人如果吃到了餐品,他就会给餐厅打x[i]分。但是由于不能马上吃到餐品,顾客就会产生不满。如果第i个人吃到餐品等待了q分钟,他就会减少打分,分数就会减少q∗y[i],这里y[i]表示顾客每分钟产生的不满度。并且每个顾客有一个等待爆发周期z[i],即每隔z[i]分钟会直接降低打分30分。当然,只要顾客吃到了餐品,他至少会给餐厅打原本分数的一半。

作为老板,你当然是可以看到所有顾客的要求的。为了让你的餐厅的总分尽量高,你决定调整出餐的顺序。请你根据给出的顾客要求,来安排出餐顺序获得最高的总分。当然不一定每位顾客都能在营业时间内获得餐品。

【输入格式】
第一行输入两个数n,m,表示共有n个人,营业时间为m分钟

接下来输入n行,每行输入四个数x[i],y[i],z[i],t[i]。x[i]表示第i个顾客如果吃到餐品会打的最高分数,y[i]表示每分钟产生的不满度,z[i]表示等待爆发周期,每个周期减少30分。t[i]表示制作该餐品所需要花费的时间。

【输出格式】
输出一行一个数,表示获得的最高总分。

【输入样例】
2 100
1000 4 30 50
500 2 50 50
【输出样例】
1020
【数据范围】
对于70%的数据,保证n≤10
对于100%的数据,保证n≤20,m≤1000,1≤x[i]≤10000,0≤y[i]≤100,1≤z[i]≤100,1≤t[i]≤100
每个顾客初始的最高分数保证是10的倍数。

  • 写回答

2条回答 默认 最新

  • 语言-逆行者 2023-04-01 16:37
    关注

    这道题目可以使用状态压缩动态规划来解决。我们可以定义状态f[j]表示状态为j时的最大总分。其中j是一个二进制数,第k位为1表示第k个顾客已经吃到了餐品。

    然后我们可以枚举下一个出餐的顾客是谁,然后更新状态。具体地,我们可以枚举所有未吃到餐品的顾客k,然后计算出他吃到餐品时的打分,然后更新状态f[j | (1 << k)]。

    最后答案就是所有状态中的最大值。

    这种方法的时间复杂度为O(m * 2^n * n),其中n为顾客数量,m为营业时间。

    已收到消息. 这道题目可以使用状态压缩动态规划来解决。我们可以定义状态f[j]表示状态为j时的最大总分。其中j是一个二进制数,第k位为1表示第k个顾客已经吃到了餐品。 然后我们可以枚举下一个出餐的顾客是谁,然后更新状态。具体地,我们可以枚举所有未吃到餐品的顾客k,然后计算出他吃到餐品时的打分,然后更新状态f[j | (1 << k)]。 最后答案就是所有状态中的最大值。 这种方法的时间复杂度为O(m * 2^n * n),其中n为顾客数量,m为营业时间。

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 20, M = 1 << N;
    int n, m;
    int x[N], y[N], z[N], t[N];
    int f[M];
    int main()
    {
        cin >> n >> m;
        for (int i = 0; i < n; i ++ ) cin >> x[i] >> y[i] >> z[i] >> t[i];
        memset(f, -0x3f, sizeof f);
        f[0] = 0;
        for (int i = 0; i < m; i ++ )
            for (int j = 0; j + 1 < 1 << n; j ++ )
            {
                if (f[j] == -0x3f3f3f3f) continue;
                f[j] = max(f[j], f[j]);
                for (int k = 0; k < n; k ++ )
                    if (!(j >> k & 1))
                    {
                        int score = x[k] - y[k] * (i + t[k]) - (i + t[k]) / z[k] * 30;
                        score = max(score, x[k] / 2);
                        f[j | 1 << k] = max(f[j | 1 << k], f[j] + score);
                    }
            }
        int res = 0;
        for (int i = 0; i < 1 << n; i ++ ) res = max(res, f[i]);
        cout << res << endl;
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 4月9日
  • 已采纳回答 4月1日
  • 创建了问题 4月1日

悬赏问题

  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并—
  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址