zoukankan      html  css  js  c++  java
  • 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方程很简单

    [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
    ",f[1][0]);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/mmlz/p/6360606.html
Copyright © 2011-2022 走看看