两道简单算法题

落花清理(优先队列)

描述:
春天的校园里有很多落花,环卫工人已经将落花扫成了n堆,为了方便处理,需要环卫工人把所有的落花合成一堆。要求合并的时候遵守以下规则:每一次合并,环卫工人把两堆落花合并到一起,消耗的体力等于两堆落花的重量之和。所有的落花经过n−1次合并之后合成一堆。环卫工人在合并落花时总共消耗的体力等于每次合并所耗体力之和。
你的任务是设计出合并的次序方案,使环卫工人耗费的体力最少,并输出这个最小的体力耗费值。

输入格式:
两行,第一行是一个整数n(1≤n≤3000),表示落花的堆数。第二行包含n个整数,用空格分隔,第i个整数ai(1≤ai≤2000)是第i堆落花的重量。

输出格式:
输出一行,这一行只包含一个整数,也就是最小的体力耗费值。

输入样例:
3
1 2 9

输出样例:
15

提示:
可以先将 1、2堆合并,新堆落花的重量为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新堆落花的重量为12,耗费体力为 12。所以总共耗费体力为3+12=15,15为最小的体力耗费值。

#include <iostream>
#include <queue>
using namespace std;
priority_queue<int, vector<int>, greater<int>> q;

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;
        q.push(x);
    }
    long long sum = 0;
    while (q.size() >= 2)
    {
        int x1 = q.top();
        q.pop();
        int x2 = q.top();
        q.pop();
        int t = x1 + x2;
        sum += t;
        q.push(t);
    }
    cout << sum << endl;
    return 0;
}

游戏高手(简单dp)

描述
小明是一位游戏高手,他最喜欢的游戏是一种吃豆子游戏:
在一个n行m列的方格内,每一个方格中有一个豆子,每一个豆子有相应的分值,当游戏玩家控制吃豆人进入
方格时就会立即吃掉该格的豆子,得到该豆子的分值,但是并不是每一次都加分,有些有毒的豆子吃了会减分。
游戏开始时,吃豆人会首先出现在最左上的方格内,玩家可以通过键盘上的上下左右键控制吃豆人向上下左右
第一次走一格,当吃豆人走到最右下的方格内时,游戏结束。
小明每次玩这个游戏都能得到非常高的分数,然而今天,他的键盘“向上”和“向左”的控制键坏了,他只能通过
键盘控制吃豆人向右和向下走,小明一下子变得不太会玩这个游戏了,他希望你帮忙,给定一个n行m列的游戏
布局,问在“向上”和“向左”两个控制键损坏的情况下,游戏结束时最多能吃到多少分数?

输入格式
第一行两个数n和m(0<m,n<=100),分别代表行数和列数。
此后n行,每行m个数(每个数在[-100,100]范围内),以空格分隔

输出格式
输出能得到的最高分数

输入样例
2 3
2 5 -2
3 -8 4

输出样例
9

提示
路径依次经过2 5 -2 4,故总分是9。

#include <iostream>
using namespace std;
int dp[110][110], a[110][110];
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> a[i][j];
        }
    }
    dp[0][0] = a[0][0];
    for (int i = 1; i < n; i++)
        dp[i][0] = dp[i - 1][0] + a[i][0];
    for (int i = 1; i < m; i++)
        dp[0][i] = dp[0][i - 1] + a[0][i];
    for (int i = 1; i < n; i++)
    {
        for (int j = 1; j < m; j++)
        {
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + a[i][j];
        }
    }
    cout << dp[n - 1][m - 1] << endl;
    return 0;
}
  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值