Gym100286C Clock
不想打题面,题面戳这里。
被这题吓到了,感觉无从下手。最后还是看着题解和别人的代码加以改编最后写出了的。其实理解之后写出了也就是三四十行的样子了。
首先题目有个很重要的条件——转动某个针只会对周期比他长的钟产生影响,这似乎就给我们开了个口子。
我们假设第\(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方程很简单
\]
考虑到调针的代价其实只跟时间差的绝对值有关(顺逆时针等价),于是我们可以把问题等价成从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][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的更多相关文章
- 修改Linux系统日期与时间date clock
先设置日期 date -s 20080103 再设置时间 date -s 18:24:30 为了永久生效,需要将修改的时间写入CMOS. 查看CMOS的时间: #clock -r 将当前系统时间写到C ...
- 操作系统页面置换算法(opt,lru,fifo,clock)实现
选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...
- Cesium应用篇:3控件(1)Clock
创建 跟Clock相关的主要有Animation控件和Timeline控件,通常两者会放在一起使用. 在Cesium中,Viewer默认开启这两个控件,如果你想要不显示控件,可以在Viewer初始化中 ...
- 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 ...
- Clock rate
https://en.wikipedia.org/wiki/Clock_rate The clock rate typically refers to the frequency at which a ...
- clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别【转】
转自:http://www.cnblogs.com/krythur/archive/2013/02/25/2932647.html 转自http://blog.sina.com.cn/s/blog_7 ...
- 最少clock
var elClock = document.getElementById("clock");var getTime = function(){ var _ = ['00','01 ...
- 用clock()函数计算多项式的运行时间
百度百科中定义clock():clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 简 ...
- 编写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, ...
随机推荐
- docker基础——关于安装、常用指令以及镜像制作初体验
为什么使用docker docker就是一个轻量级的虚拟机,他解决的是服务迁移部署的时候环境配置问题.比如常见的web服务依赖于jdk.Tomcat.数据库等工具,迁移项目就需要在新的机器重新配置这些 ...
- opendaylight安装
OpenDaylight安装 环境 jdk-1.8 maven 环境配置安装 Java环境 查看Java环境 java -version 安装jdk-1.8 yum install java-1.8 ...
- VM虚拟机里的Ubuntu系统怎么设置屏幕分辨率
说白了就是安装VMWare tools工具,步骤如下: 1)在VMWare中启动ubuntu虚拟机 2)在VMWare中:右键单击启动虚拟机,点击[安装vmware tools] 3)在ubuntu中 ...
- CSS选取指定位置标签first-child、last-child、nth-child
1.first-child 选择列表中的第一个标签. 2.last-child 选择列表中的最后一个标签 3.nth-child(n) 选择列表中的第n个标签 4.nth-child(2n) 选择列表 ...
- Python常用函数记录
Python常用函数/方法记录 一. Python的random模块: 导入模块: import random 1. random()方法: 如上如可知该函数返回一个[0,1)(左闭右开)的一个随机的 ...
- 裸机——210SD卡启动
1.通过阅读iROM_Application_note可以获取关于启动的全部信息 2.记录下代码 制作SD卡启动的代码,即添加校验和的 #include <strings.h> #incl ...
- 26-dotnet watch run 和attach到进程调试
1-打开vscode, 按下Ctrl+`,打开命令行窗口 创建一个donet core mvc项目 2-打开刚刚创建的文件夹 3-输入 dotnet run 访问网站 4 -F5键即可调试 5-更改代 ...
- java实时监听日志写入kafka
目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...
- JDBC---java与数据库中数据类型的对应关系
基础数据类型 Java 类型 SQL 类型 int 或 java.lang.Integer INTEGER long 或 java.lang.Long BIGINT short 或 java.lang ...
- android onNewIntent 为什么要在onNewIntent的时候要显示的去调用setIntent
原因: 当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getInte ...