The 2023 ICPC Asia Regionals Online Contest (2)-2023 ICPC网络赛第二场部分题解 I,M

博客介绍了两道算法题,一是M Dirty Work,涉及数学期望与贪心算法,需算出每道题AC耗时期望并排序求最小期望罚时;二是I Impatient Patient,基于数学期望,要在最优策略下枚举挑战点求恢复所需的期望时间,均给出思路和代码相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

M Dirty Work (数学期望/贪心)<签到题>

 I Impatient Patient(数学期望)<签到题>


原题地址:PTA | 程序设计类实验辅助教学平台 (pintia.cn)

M Dirty Work (数学期望/贪心)<签到题>

It is another ICPC contest. Your teammates sketched out all solutions to the problems in a fraction of a second and went away to celebrate, but now you are stuck at implementing them!

There are n problems in total, the i-th of which will take ai​ seconds to implement. You have the flexibility to choose any unsolved problem to implement, either at the beginning of the contest or right after solving the previous problem.

The total penalty is calculated in a similar manner to ordinary ICPC contests. If you submit and pass problem i at time ti​, the total penalty is ∑i=1n​ti​. Note that unsuccessful submissions are omitted from penalty calculations for the sake of convenience.

After completing the implementation of a problem, you will submit it immediately. However, there is a probability pi​ that your code for the i-th problem fails. In such cases, it will take additional bi​ seconds to fix and re-implement the code, and you must address the issue promptly without switching to another problem. It is guaranteed that the second attempt will always succeed.

Now you wonder what the minimal expected total penalty is if you employ an optimal strategy for selecting the next problem to implement.

Input

The first line contains a positive integer T (1≤T≤104), denoting the number of testcases.

For each testcase:

  • The first line contains one integer n (1≤n≤5000), denoting the number of problems.
  • The following n lines each contain two integers ai​ and bi​ (1≤ai​,bi​≤104), as well as one decimal number pi​ (0≤pi​≤1). These values represent the time required for the first and second attempts, respectively, as well as the probability of failure for the first attempt. The decimal number pi​ has exactly one decimal place.

It is guaranteed that ∑n≤106, and ∑i=1n​(ai​+bi​)≤18000 for each testcase, so that you can always solve all problems in five hours.

Output

For each testcase, print one decimal number, denoting the minimal expected total penalty if you employ an optimal strategy for selecting the next problem to implement. The answer will be considered correct if its absolute or relative error is less than 10−9.

Sample Input

3
3
6 1 1.0
5 1 1.0
4 1 1.0
2
4 100 0.9
70 1 0.5
7
222 848 0.4
501 640 0.6
1534 495 0.7
1132 1433 1.0
1552 171 1.0
1777 25 0.2
1325 2325 0.8

Sample Output

34.000000000000
235.000000000000
38937.900000000001

Notes

In the first test case, you should tackle problem 3 first, followed by problem 2, and finally problem 1.

代码长度限制

64 KB

时间限制

1000 ms

内存限制

512 MB

 题目大意:

共有n道题,每道题有(1-pi)的概率需要 ai 的时间AC,有 pi 的概率需要(ai+bi)的时间AC,

现给出n道题的ai,bi,qi,求做完所有题目需要的最小期望罚时。

根据ICPC规则,对于第i道题,它的罚时为从比赛开始直到它被AC的总时间。

思路:

算出每道题AC耗时的期望 p[i] 再对期望从小到大排序。

代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N=5010;
double p[N];

void solve(int n1)
{
	int a,b;
	double c;
	for(int i=0;i<n1;i++)
	{
		cin>>a>>b>>c;
		p[i]=a*(1-c)+(a+b)*c;
	} 
	sort(p,p+n1);
	double sum=0,ans=0;
	for(int i=0;i<n1;i++)
	{
		ans+=p[i];
		sum+=ans;
	}
	printf("%.12lf",sum);
	return ;
}

int main()
{
	int n;
	cin>>n;
	int n1;
	for(int i=0;i<n;i++)
	{
		cin>>n1;
		solve(n1);
        if(i!=n-1)
            cout<<endl;
	}
}

 I Impatient Patient(数学期望)<签到题>

You accidentally sprained your ankle, and now you are facing a long recovery phase. Initially, you are at stage 0, and your recovery progresses until you reach stage n.

Each day, if you rest properly, you advance by exactly one stage. So it takes n days for you to recover, that is, if you do not do anything improper.

However, instead of resting, you have the option to challenge yourself, which also takes one day. If you are at stage i and succeed, you will instantly recover. However, if you fail, you will regress to stage ai​ (0≤ai​≤i). The probability of success is pi​.

Now, you are wondering what the expected time required for your recovery would be, assuming you adopt the best strategy.

Input

The first line contains a positive integer T (1≤T≤104), denoting the number of test cases.

For each test case:

  • The first line contains one integer n (1≤n≤5×105), denoting the number of stages of recovery.
  • The next line contains n integers a0​,a1​,⋯,an−1​ (0≤ai​≤i), denoting the stage you will go back to if you fail at stage i.
  • The next line contains n integers q0​,q1​,⋯,qn−1​ (0≤qi​≤105), where pi​=qi​/105 denotes the probability of success at stage i.

It is guaranteed that ∑n≤5×105.

Output

For each test case, print one decimal number, denoting the expected time needed for you to recover if you take the best strategy. The answer will be considered correct if its absolute or relative error is less than 10−9.

Sample Input

5
1
0
0
3
0 1 2
99999 0 0
3
0 1 2
0 50001 100000
5
0 1 2 0 1
21735 25194 37976 89936 99999
8
0 0 2 2 4 3 4 1
12839 27084 17777 35472 31951 64686 96898 0

Sample Output

1.000000000000
1.000010000100
2.999960000800
4.447607187333
7.096039133935

代码长度限制

64 KB

时间限制

1000 ms

内存限制

512 MB

题目大意:

共n个阶段,要从第0个阶段到达第n个阶段,有两种方法:(1)每天走一个阶段,第n天后到达第n个阶段。(2)开启“挑战” 模式,成功直接到第n阶段,成功概率为p/1e5;失败则回到第a[i]阶段.

思路:

最优策略下,只会在一个点挑战,该点成功即到达第n阶段,枚举每个点作为挑战点,取最小值。

代码:

#include<iostream>
using namespace std;
const int N=500010;
const int W=1e5;
double dp[N];
int a[N];
long long int p[N];

void solve()
{
	int n1;
	cin>>n1;
	for(int i=0;i<n1;i++)
		cin>>a[i];
	for(int i=0;i<n1;i++)
		cin>>p[i];
	double res=n1;
	for(int i=0;i<n1;i++)
	{
		if(!p[i])
			continue;//成功概率=0则跳过不进行下面的计算。 
		double q = 1.0 * p[i] / 100000;//成功的概率 
		
        // 先走i步走到 第i位置;
        // 花费1次"赌命",看是否成功;共花费i + 1 
        // 成功的期望次数为1/q次 所以需要1/q-1次失败(前1/q-1次都是失败的,第1/q次成功)
		//如:q=0.2,则1/0.2=5,即平均做5次试验就会有一次成功。(10*0.2=2,即10次试验有两次成功) 
        // 每次失败,需要再多走 i-a[i]+1次,多的一次是用来"赌命" 
        dp[i] = 1.0 * i + 1 + (1.0/q-1) * (i - a[i] + 1);
        res = min(dp[i], res);
    }
    printf("%.12lf",res);
}

int main()
{
	int n;
	cin>>n;
	while(n--)
    {
        solve();
        if(n)
            cout<<endl;
    }
### 参与ICPC亚洲日本区线上第一轮比的信息和规则 #### 比概述 国际大学生程序设计竞(International Collegiate Programming Contest, ICPC)是一项全球性的编程竞活动。其中,ICPC亚洲区域分为多个区,包括中国、韩国以及日本等地的比。对于希望参加ICPC Asia Japan Online First-Round Contest的学生来说,了解具体的参信息至关重要。 #### 报名条件 通常情况下,只有在校本科生或者研究生可以组队报名参加此类事[^1]。每支队伍由三名队员组成,并且需要指定一名指导教师负责监督整个过程。需要注意的是,不同年份的具体规定可能会有所变化,因此建议关注官方发布的最新通知来获取最准确的要求。 #### 注册流程 为了能够顺利参与到比中去,团队应该尽早完成在线注册手续。这一般涉及到填写基本信息表格并提交给主办方审核通过之后才能正式成为参者之一。此外,在线平台还会提供练习环境供选手熟悉系统操作方式及其功能特性[^2]。 #### 事形式 该类竞多采用限时解题的形式来进行考核,即给出若干道算法题目让各小组在规定时间内解答尽可能多的问题以获得更高分数。期间允许查阅资料但严禁作弊行为的发生。值得注意的是,由于这是线上初选阶段,所以不存在现场答辩环节[^3]。 #### 准备工作 准备过程中除了要掌握扎实的数据结构与算法基础知识外,还应当注重培养良好的协作沟通能力以便于更好地发挥集体智慧解决问题。另外也可以参考往届真题集锦加深理解常见考点分布情况从而提高实战水平[^4]。 ```cpp // 示例代码用于展示如何处理输入输出流加速读取效率 #include<bits/stdc++.h> using namespace std; void solve(){ // 解决具体问题逻辑实现部分... } signed main(){ ios::sync_with_stdio(false); int T; cin >> T; while(T--)solve(); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值