小偷分赃 等比求和 CodeChef Bank robbery

https://s3.amazonaws.com/codechef_shared/download/translated/SEPT15/mandarin/BANROB.pdf

题目描述

        两个江洋大盗(大厨也是其中之一,当然是更厉害的那个)在 Churuland 国家银行的金库里相遇了。他们都吓尿了!事实上,他们都没想到会在这样的地方遇到一位同样想来洗劫银行在 Churufest 2015 期间积累的资金的同行。

       他们统计了金库中的钱,恰好为十亿。现在他们要决定如何瓜分这些钱。有一个问题是:在警察赶到之前,他们只剩 M 分钟可以撤离银行。同时,他们在金库里呆的越久,最终能搬走的钱就越少。正式地说,他们马上走的话可以带走十亿元,但如果他们选择 t 分钟后走,他们就只能带走 10亿 × pt 元,其中 p 是一个不大于 1 的非负常数。而当 t = M 时,他们就会被捕,也带不走任何钱。然而,在他们确定分赃方案之前,他们是不会离开的。

       分赃的过程是这样的:从第一分钟起(即 t = 0),在每分钟的开始,他们中的一人会提出一个分赃方案,如果对方同意,他们就会照此方案带钱离开,否则他们就等到下一分钟的开始,由另一方提出方案。为了不被抓获,他们最晚只能在第 M 分钟的开始提出方案(即t = M − 1)。两个贼都想最大化自己的收获,但如果有两个方案他能拿到一样多的钱,他会选择盗走的总金额更大的那个。他们就要开始分赃了,而大厨将第一个提出方案。你想知道最后的分赃方案会是什么,假设两位大盗都以最优策略选择并且钱是可以以任意实数金额拆分的。

题解:

       https://discuss.codechef.com/questions/74775/banrob-editorial

PROBLEM LINK:

Practice
Contest

Author: Kirill
Tester: Kevin Atienza
Editorialists: Pushkar Mishra and Suhash Venkatesh

DIFFICULTY:

Easy

PREREQUISITES:

Math, Binary Exponentiation, Sum of Geometric Progression

PROBLEM:

Given that two thieves have  1  billion to divide amongst them according to a particular method, report the amounts both the thieves will receive upon division. The particular method here is that after a certain amount of time  t , only (1 Billion *  pt ) amount of money can be taken, where  0p1 . Also, there are only  M  minutes to divide the stolen money and escape.

EXPLANATION:

Subtask 1
Let us start by taking an example. Let  p  = 0.5 and  t  = 4. We not proceed minute by minute.

  • First minute
    Money left to take =  109 .
    Thief 1 to propose a plan.

  • Second minute
    Money left to take =  1090.5 .
    Thief 2 to propose a plan.

  • Third minute
    Money left to take =  1090.52 .
    Thief 1 to propose a plan.

  • Fourth minute
    Money left to take =  1090.53 .
    Thief 2 to propose a plan.

After the fourth minute, both the thieves will lose all the money. So, let's go back in time minute by minute and see what the optimal division would be.

  • If in the fourth minute, Thief 2 proposes a division of  0  and  1090.53  respectively, Thief 1 will accept it.
  • If in the third minute, Thief 1 proposes a division of  1090.52(1090.53)  and  1090.53  respectively, Thief 2 will accept it.
  • If in the second minute, Thief 2 proposes a division of  1090.5(1090.52)+(1090.53)  and  (1090.52)(1090.53)  respectively, Thief 1 will accept it.
  • Finally, if in the second minute, Thief 1 proposes a division of  109(1090.5)+(1090.52)(1090.53)  and  (1090.5)(1090.52)+(1090.53)  respectively, Thief 2 will accept it.

The acceptances will be because the theif accepting the plan can in no way gain more money in the future than being offered at that point in time. Please note this point in the question:
"Each thief wants to maximize his earnings, but if there are two plans with the same amounts for him, he would choose the one which leads to a larger total amount of stolen dollars."

We can make a very important observation here. The amount that Thief 1 will gain is given by:
val  =  109(p0p1+p2p3pM1) . Thus, the amount that Thief 2 gets is  109val .

Subtask 2
If we observe the terms inside the bracket in the expression we got for  val  in subtask 1, we can see that it is basically the summation of terms of a Geometric Progression (GP).
The GP is:  1 p p2 p3

We common ratio  r  =  p  and the first term of GP  a  =  1 . The formula to calculate the sum of first  n  terms of a GP is well known:
S=a(rn1)r1

Thus, in this case,  S=((p)M1)(p)1 .
This will work in  O(M)  with linear exponentiation.

Subtask 3
The solution of subtask 2 can be optimised by using binary exponentiation to calculate  (p)M . This will allow us to compute the sum of the GP in  O(logM) .

COMPLEXITY:

O(logM)  per test case.

SAMPLE SOLUTIONS:

Author
Tester
Editorialist

#include<bits/stdc++.h>

using namespace std;

#define VAL (int)1e9

int main() {
	int T, M;
	double p;
	scanf("%d", &T);
	while (T--) {
		scanf("%d%lf", &M, &p);
		double fst = VAL * (1 - pow(-p, M)) / (p + 1);
		double snd = VAL - fst;
		printf("%.4lf %.4lf\n", fst, snd);
	}
	return 0;
}


       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的代码示例,可以从数据集中提取光流图并应用于i3d网络: ```python import os import cv2 import numpy as np # 定义数据集文件夹和光流图文件夹路径 data_dir = "C:/crime" frames_dir = "C:/crime/crime_frames" # 定义光流图的分辨率和时间跨度 flow_resolution = (224, 224) flow_timestep = 1 # 循环遍历数据集中的每个类别 for class_name in os.listdir(data_dir): # 获取当前类别的文件夹路径 class_dir = os.path.join(data_dir, class_name) # 循环遍历当前类别中的每个视频 for video_name in os.listdir(class_dir): # 获取当前视频的文件夹路径 video_dir = os.path.join(class_dir, video_name) # 获取当前视频的光流图文件夹路径 flow_dir = os.path.join(frames_dir, class_name, video_name) # 如果光流图文件夹不存在,则创建它 if not os.path.exists(flow_dir): os.makedirs(flow_dir) # 读取当前视频中的每一帧 frames = [] for frame_name in os.listdir(video_dir): frame_path = os.path.join(video_dir, frame_name) frame = cv2.imread(frame_path) frames.append(frame) # 将帧转换为灰度图像 gray_frames = [cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) for frame in frames] # 计算光流图 flows = [] for i in range(0, len(gray_frames) - 1, flow_timestep): prev_gray = gray_frames[i] curr_gray = gray_frames[i + flow_timestep] flow = cv2.calcOpticalFlowFarneback(prev_gray, curr_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) flow = cv2.resize(flow, flow_resolution) flows.append(flow) # 将光流图保存到文件夹中 for i, flow in enumerate(flows): flow_path = os.path.join(flow_dir, "{:05d}.jpg".format(i)) np.save(flow_path, flow) ``` 代码解释: 1. 首先定义了数据集文件夹和光流图文件夹的路径。 2. 然后循环遍历数据集中的每个类别,每个类别都有一个文件夹名字。 3. 对于每个类别,循环遍历其中的每个视频,每个视频也有一个文件夹名字。 4. 对于每个视频,获取它的光流图文件夹路径,如果该文件夹不存在,则创建它。 5. 读取每个视频的所有帧,并将它们转换为灰度图像。 6. 计算光流图,使用cv2.calcOpticalFlowFarneback函数计算两帧之间的光流。 7. 将光流图保存到光流图文件夹中,以.npy格式保存。 最后,我们可以将生成的光流图应用于i3d网络进行分类任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值