Codeforce算法题 | 你能想出解法,让你的基友少氪金吗?
在TechFlow学长的公众号里发现一道挺有意思的CF算法题,现在利用学长的思路学习一下
题目链接:https://codeforces.com/contest/1418/problem/C
题意
这道题的题意也很有意思,背景也是游戏。说是有一天你和你的基友一起在家打游戏,这个游戏一共有n个boss。这些boss的难度不同,有些boss简单,有些boss困难。你的技术要比基友的好一些,你们两人轮流打boss。
游戏规定每次进行游戏最少打1个boss,最多打两个boss。由于你的实力更好,你可以战胜所有的boss。但是你的基友比较菜,只能打得过简单的boss,如果碰上hard模式的boss就只能氪金。基友的钱也是钱,你们希望在尽量少氪金的前提下把游戏通关。现在已知所有boss的难易情况并且基友先开始游戏,请问在最佳策略下,最少需要氪金多少次?
样例
首先给定一个数字t,表示测试数据组数。对于每组数据,给定一个数字n,表示boss的数量。接着给定n个0或者1的整数,0表示boss是简单模式,1表示是困难模式。要求返回一个数字,即最少的氪金次数。其中
\]
input:
8
1 0 1 1 0 1 1 1
output:
2
样例解释
基友先杀1和2两个boss,氪金一次。
“我”杀3和4号boss
基友杀5号boss
“我”杀6和7号boss
基友击杀8号boss,氪金一次,总共氪金两次。
题解
这道题我们最先想到的可能就是贪心,比如我们可以想到一种贪心策略,就是每次基友杀怪的时候先杀1个,然后看第二个是0还是1,如果是0的则一起杀了,否则不杀留给“我”。
我们可以用之前介绍过的等价判断法来判断一下这个贪心策略可不可行,对于这道题而言,贪心的本质是让氪金的次数最少。所以当基友的第二个怪是0的时候,杀和不杀对于当前的氪金次数来说是没有影响的。但是对于后面的局面是会有影响的,并且可能会出现不同的结果。
比如我们可以找到一个例子10011,基友杀不杀第二个怪,直接影响后面的结果。如果基友杀了,那么不论“我”怎么选,基友都必须要至少再氪金一次。如果基友不杀,那么“我”杀第二个怪,基友再杀第三个怪,最后两个boss都交给“我”,那么基友全局只需要氪金一次。所以贪心算法不可行。
动态规划
如果你熟悉动态规划的话,那么几乎可以发现这是一道经典的动态规划问题。对于每一个怪来说,它都有两种状态,分别是被基友杀或者是被“我”杀。我们用0和1来分别表示,0表示被基友杀,1表示被“我”杀。一共有n个怪,所以我们可以用一个n * 2的数组来记录所有怪的状态。
对于第i个怪而言,如果它是被“我”杀的,那么它可以由基友杀了i-1或者是i-2个怪的状态转移得到。比如如果从基友杀了i-1转移得到,说明“我”杀了i,否则说明“我”不仅杀了i,还杀了i-1。同理i被基友杀的情况也是一样,所以这个状态转移方程就非常明显了。
# 学长的Python解法,注释满满
import sys
t = int(input())
for _ in range(t):
n = int(input())
arr = list(map(int, input().split(' ')))
dp = [[sys.maxsize, sys.maxsize] for _ in range(n+2)]
dp[0][1] = 0
for i in range(1, n+1):
if i > 1:
# 如果i > 1,那么说明可以杀两个
# 0表示基友杀怪的情况,基友可以杀1个从i-1转移得到,也可以杀2个从i-2转移得到
# 需要加上氪金的次数
dp[i][0] = min(dp[i-1][1] + arr[i-1], dp[i-2][1] + arr[i-2] + arr[i-1])
# 我杀怪不用氪金,直接赋值即可
dp[i][1] = min(dp[i-1][0], dp[i-2][0])
else:
# i=1,那么只能杀一个
dp[i][0] = dp[i-1][1] + arr[i-1]
dp[i][1] = dp[i-1][0]
print(min(dp[n][0], dp[n][1]))
// 蒟蒻C++解法
// Author : RioTian
// Time : 20/11/07
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int main() {
// freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int x, ans = 0, sum = 0;
n--;
cin >> ans;
while (n--) {
cin >> x;
if (x)
sum++;
else
ans += sum / 3, sum = 0;
}
cout << ans + sum / 3 << endl;
}
}
最后,这道题非常的基础,可以说是动态规划的基础问题了。如果对动态规划这个概念不是很熟悉的话,非常建议动手做一做,加深一下印象。
Codeforce算法题 | 你能想出解法,让你的基友少氪金吗?的更多相关文章
- LeetCode算法题-First Bad Version(Java实现-三种解法)
这是悦乐书的第200次更新,第210篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第66题(顺位题号是278).您是产品经理,目前领导团队开发新产品.不幸的是,您产品的最 ...
- LeetCode算法题-Longest Palindrome(五种解法)
这是悦乐书的第220次更新,第232篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第87题(顺位题号是409).给定一个由小写或大写字母组成的字符串,找到可以用这些字母构 ...
- LeetCode算法题-Find the Difference(Java实现-五种解法)
这是悦乐书的第214次更新,第227篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第82题(顺位题号是389).给定两个字符串s和t,它们只包含小写字母.字符串t由随机混 ...
- LeetCode算法题-Reverse Vowels of a String(Java实现-四种解法)
这是悦乐书的第206次更新,第218篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第74题(顺位题号是345).编写一个函数,它将一个字符串作为输入,并仅反转一个字符串的 ...
- LeetCode算法题-Missing Number(Java实现-四种解法)
这是悦乐书的第200次更新,第209篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第65题(顺位题号是268).给定一个包含n个不同数字的数组,取自0,1,2,...,n ...
- LeetCode算法题-Add Digits(Java实现-3种解法)
这是悦乐书的第199次更新,第207篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第63题(顺位题号是258).给定非负整数num,重复添加其所有数字,直到结果只有一位数 ...
- LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)
这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个 ...
- LeetCode算法题-Number Complement(Java实现-五种解法)
这是悦乐书的第240次更新,第253篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第107题(顺位题号是476).给定正整数,输出其补码数.补充策略是翻转其二进制表示的位 ...
- LeetCode算法题-Third Maximum Number(Java实现-四种解法)
这是悦乐书的第222次更新,第235篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第89题(顺位题号是414).给定非空的整数数组,返回此数组中的第三个最大数字.如果不存 ...
随机推荐
- MFC 简介
参考:https://baike.baidu.com/item/MFC/2236974 MFC (微软基础类库) 编辑 锁定 讨论999 MFC(Microsoft Foundation Clas ...
- LiteOS-任务篇
目录 前言 链接 参考 笔录草稿 基本概念 任务相关概念 LiteOS 任务运作机制 内核初始化 创建任务 创建任务有两种方案 任务相关函数 任务开发流程 创建创建任务 部分源码 例子 创建任务的任务 ...
- 50个你必须了解的Kubernetes面试问题
Kubernetes一直是当今业界的流行语,也是最好的编排工具.它吸引了许多想要提升自己职业生涯的经验丰富的专业人士.HuaWei,Pokemon,Box,eBay,Ing,Yahoo Japan,S ...
- 实时,异步网页使用jTable, SignalR和ASP。NET MVC
下载source code - 984.21 KB 图:不同客户端的实时同步表. 点击这里观看现场演示. 文章概述 介绍使用的工具演示实现 模型视图控制器 遗言和感谢参考历史 介绍 HTTP(即web ...
- Git本地已有项目关联远程仓库
情况: 本地已有项目 远程有个仓库 目的: 本地项目关联远程仓库 首先要把本地项目变成git管理的,也就是建立一个本地仓库,可以在项目目录下面使用git init命令初始化仓库,初始化成功之后会在仓库 ...
- 异步编程新方式async/await
一.前言 实际上对async/await并不是很陌生,早在阮大大的ES6教程里面就接触到了,但是一直处于理解并不熟练使用的状态,于是决定重新学习并且总结一下,写了这篇博文.如果文中有错误的地方还请各位 ...
- day58 Pyhton 框架Django 01
内容回顾 python基础 网路编程 并发编程 数据库 前端 osi7层 tcp/ip 5层模型 应用层 表示层 ...
- 浅谈MircoPython---ESP8266
一.连接WIFI 在Putty会话窗口输入 >>>help() 打印的消息会告诉你如何连接WIFI import network sta_if = network.WLAN(netw ...
- readcf: option RunAsUser: unknown user smmsp发送邮件失败问题
今天使用mail命令发送邮件时,发送不了,错误信息如下: /etc/mail/submit.cf: line 432: readcf: option RunAsUser: unknown user s ...
- java中的三大注解
三大注解的作用 Java三大注解分别是@Override @Deprecated @Suppresswarnings @Override 注解表名子类中覆盖了超类中的某个方法,如果写错了覆盖形式,编译 ...