不想打题面,题面戳这里

被这题吓到了,感觉无从下手。最后还是看着题解和别人的代码加以改编最后写出了的。其实理解之后写出了也就是三四十行的样子了。

首先题目有个很重要的条件——转动某个针只会对周期比他长的钟产生影响,这似乎就给我们开了个口子。

我们假设第\(i\)根针有\(D_{i-1}\)的刻度(第一根针 \(60\) 个刻度),然后我们会惊奇地发现,当第\(i\)根针运行一个周期后,第\(i+1\)根针恰好移动一个刻度。因为假设第\(i\)根针周期为\(T\),第\(i+1\)根针的周期就是\(D_iT\)。然后\(i\)这根指针转了一周,\(i+1\)恰好转了\(\frac{1}{D_i}\)周,也就是一个刻度。于是我们可以用\(cost_i\)记录下第\(i\)根针移动一个刻度所需要最小代价,dp方程很简单

\[cost_i = \min \{ cost_{i-1}*D_{i-1}, \frac{2 \pi L_i}{D_i} \}
\]

考虑到调针的代价其实只跟时间差的绝对值有关(顺逆时针等价),于是我们可以把问题等价成从0时刻将针调至时间差绝对值这个时刻所需要的最小代价。我们可以看看目标时刻指针所只在的位置,由于可能在两个位置中间,我们可以取下整。然后这个可以用进制转换一样的思想来处理,第\(i\)根指针用\(val_i\)记录。为什么取下整呢?后面你就会慢慢理解。

接下来,就是这道题目最核心的dp部分了。我们用\(f_{i,0}\)表示将第\(i\)根指针转至\(val_i\)位置所需要的最小代价,\(f_{i,1}\)表示将第\(i\)根指针转至\(val_i+1\)位置所需要的最小代价。由于周期长的不能影响周期短的,我们可以从后往前dp。我们如果已经把第\(i\)根针安放在\([val_i,val_i+1)\)这段区间里面,那么移动周期比他短的指针时候也会在这个区间里面。因为\(i-1\)这根针我们最多转动一个周期,所以\(i\)这个针最多移动一个刻度,我们可以在dp方程中保证其合法性。然后根据针可以顺时针转也可以逆时针转,可以得出

\[f[i][0] = \min(f[i+1][1]+(D[i]-val[i])*cost[i],f[i+1][0]+val[i]*cost[i])\\
f[i][1] = \min(f[i+1][1]+(D[i]-val[i]-1)*cost[i],f[i+1][0]+(val[i]+1)*cost[i])\]

这两个方程,最后答案就是\(f[1][0]\)了。

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std; typedef long long ll;
const int maxn = 55; const double pi = acos(-1.0);
int N,D[maxn],L[maxn],val[maxn]; ll T1,T2,T;
double cost[maxn],f[maxn][2]; int main()
{
freopen("clock.in","r",stdin);
freopen("clock.out","w",stdout);
scanf("%d",&N);
for (int i = 2;i <= N;++i) scanf("%d",D+i);
for (int i = 1;i <= N;++i) scanf("%d",L+i);
D[1] = 60; cost[1] = 2*pi*L[1]/D[1];
for (int i = 2;i <= N;++i) cost[i] = min(cost[i-1]*D[i-1],2*pi*L[i]/D[i]);
cin >> T1 >> T2; T = abs(T1-T2);
for (int i = 1;i <= N&&T;T /= D[i++]) val[i] = T%D[i];
for (int i = N;i;--i)
{
f[i][0] = min(f[i+1][1]+(D[i]-val[i])*cost[i],f[i+1][0]+val[i]*cost[i]);
f[i][1] = min(f[i+1][1]+(D[i]-val[i]-1)*cost[i],f[i+1][0]+(val[i]+1)*cost[i]);
}
printf("%.10lf\n",f[1][0]);
fclose(stdin); fclose(stdout);
return 0;
}

Gym100286C Clock的更多相关文章

  1. 修改Linux系统日期与时间date clock

    先设置日期 date -s 20080103 再设置时间 date -s 18:24:30 为了永久生效,需要将修改的时间写入CMOS. 查看CMOS的时间: #clock -r 将当前系统时间写到C ...

  2. 操作系统页面置换算法(opt,lru,fifo,clock)实现

    选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...

  3. Cesium应用篇:3控件(1)Clock

    创建 跟Clock相关的主要有Animation控件和Timeline控件,通常两者会放在一起使用. 在Cesium中,Viewer默认开启这两个控件,如果你想要不显示控件,可以在Viewer初始化中 ...

  4. get back to the slower clock rate that allows it to save more power

    http://www.howtogeek.com/177790/why-you-cant-use-cpu-clock-speed-to-compare-computer-performance/ Wh ...

  5. Clock rate

    https://en.wikipedia.org/wiki/Clock_rate The clock rate typically refers to the frequency at which a ...

  6. clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别【转】

    转自:http://www.cnblogs.com/krythur/archive/2013/02/25/2932647.html 转自http://blog.sina.com.cn/s/blog_7 ...

  7. 最少clock

    var elClock = document.getElementById("clock");var getTime = function(){ var _ = ['00','01 ...

  8. 用clock()函数计算多项式的运行时间

    百度百科中定义clock():clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 简 ...

  9. 编写Java应用程序。首先,定义一个时钟类——Clock,它包括三个int型 成员变量分别表示时、分、秒,一个构造方法用于对三个成员变量(时、分、秒) 进行初始化,还有一个成员方法show()用于显示时钟对象的时间。其次,再定义 一个主类——TestClass,在主类的main方法中创建多个时钟类的对象,使用这 些对象调用方法show()来显示时钟的时间。

    package com.hanqi.test; public class Clock { int hh; int mm; int ss; String time; Clock(int h,int m, ...

随机推荐

  1. 【ODT】cf896C - Willem, Chtholly and Seniorious

    仿佛没用过std::set Seniorious has n pieces of talisman. Willem puts them in a line, the i-th of which is ...

  2. html中table,tr,td

    table表格,tr表格中的行,tr表格中的列,等级关系是table>tr>td, 当然表格中还包括thead,tbody,tfoot,th,但由于浏览器支持缘故很少使用.另外table在 ...

  3. Android内购订单验证 --- nodejs实现

    主代码: function AndroidPlayVerify(inappPurchaseData, inappDataSignature) { let verify = crypto.createV ...

  4. 数据分析处理库Pandas——显示设置

    获取最多打印行数 显示内容超出部分打印成省略号. 设置最多打印行数 获取最多打印列数 显示内容超出部分打印成省略号. 设置最多打印列数 获取打印字符串的最大长度 显示内容超出部分打印成省略号. 设置打 ...

  5. C语言字符篇(四)字符串查找函数

      #include <string.h>   char *strchr(const char *s, int c);   The strchr() function returns a ...

  6. POJ 3171 区间最小花费覆盖 (DP+线段树

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4245   Accepted: 1429 D ...

  7. sql查询平均下单时间

    SQL查询订单平均审核时长 今天在写一个sql,需求是算一个订单在执行状态中的各个节点的时长 比如在订单中,状态0为开始接单,状态3为已经审核,那么现在需要计算每个客服的平均审核时长 像图中所示:这个 ...

  8. 笔记-python lib-pymongo

    笔记-python lib-pymongo 1.      开始 pymongo是python版的连接库,最新版为3.7.2. 文档地址:https://pypi.org/project/pymong ...

  9. centso下如何解压RAR文件

    tar -xvf rarlinux-3.9.3.tar.gz cd rar   make 看见下面这些信息就是安装成功了 mkdir -p /usr/local/bin mkdir -p /usr/l ...

  10. Git从入门到熟练

    Git的特性 1. 分布式版本控制 集中式VS分布式 保存更新时的文件快照而非差异 (快照 :是文件系统中的概念或者技术:来自照相领域的概念,是指特定时间点的一个状态) 其他系统在每个版本中记录着各个 ...