bzoj4428 [Nwerc2015]Debugging(数论+记忆化搜索)

bzoj4428 [Nwerc2015]Debugging(数论+记忆化搜索)

说下做这个题的初衷,这题第一次见是在2018年在一份pdf上看到的,当时不会,怎么理解都不懂,然后就在2019-9-15的上海网络赛上见到了数据增强后的原题,由于看完题解还是不会,寻思着补一下小范围数据的原题吧。

PS:发现UOJ这个新大陆。

题目链接:传送门

题意:

​ 有一个n行代码的程序存在一个bug,现在要定位这个bug,可以在 i i i 行末尾加 p r i n t print print语句,运行后你可以看出bug在第 i i i 行下面,还是第 i i i 行上面(包括第 i i i行),但是运行一个程序需要 r r r分钟,加一个 p r i n t print print语句需要 p p p分钟。问在最坏的情况下,最少多少时间能定位到这个bug。

思路:

我们用 d p [ i ] dp[i]​ dp[i]表示长度为 i i​ i行的bug需要的最少时间。所以我们可以枚举这次运行时添加的 p r i n t print​ print语句,设为 j j​ j,那么 d p [ i ] = m i n ( d p [ n j + 1 ] + j p + r ) , j [ 1 , n 1 ] dp[i]=min(dp[\lceil \frac{n}{j+1} \rceil]+j*p+r),j\in[1,n-1]​ dp[i]=min(dp[j+1n]+jp+r),j[1,n1]

考虑到 n k \lceil\frac{n}{k}\rceil kn只有 O ( n ) O(\sqrt n) O(n )种值,我们可以优化下直接取所有不同取值,对于每种取值取 k k k最小的。

怎么取 n k \lceil\frac{n}{k}\rceil kn的所有取值呢?其实列个映射关系就看出来其中的奥妙了

  1. i = n i=n i=n
  2. l a s t = n n i last=\lceil\frac{n}{\lceil \frac{n}{i} \rceil}\rceil​ last=inn
  3. 那么 j = n l a s t j=\lceil\frac{n}{last}\rceil j=lastn 是一个解
  4. i = l a s t 1 i=last-1 i=last1,如果 i > 0 i>0 i>0返回第二步

至于这道题,dp过程中注意到 n k \frac{n}{k}​ kn的分目不能等于 1 1​ 1,然后用记忆化搜索优化即可,据某博客说时间复杂度为 O ( n 3 4 ) O(n^{\frac{3}{4}})​ O(n43)

代码

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e6+20;
const int inf=0x3f3f3f3f;
ll f[N],r,p;
ll cdiv(ll a,ll b)
{
    return (a+b-1)/b;
}
ll dfs(ll n)
{
    if(n==1) return 0;
    if(f[n]) return f[n];
    ll ans=1ll << 62;
    for(ll i=n,last;i > 1 ; i=last-1)//不能取到自身
    {
        last=cdiv(n,cdiv(n,i));
        ll j=cdiv(n,last);
        ans=min(ans,dfs(j)+(last-1)*p+r);
    }
    return f[n]=ans;
}
int main()
{
    ll n;
    cin>>n>>r>>p;
    cout<<dfs(n)<<endl;
}

数据增强的题目链接:传送门

全部评论

相关推荐

01-24 12:50
门头沟学院 C++
投票
菜狗二号:还有啥想的 指定国有行啊,去了就开始幸福美满的生活了,选华子不是折腾自己么,最终财富积累度是差不多的,但是幸福指数是相差甚远的
点赞 评论 收藏
分享
spiritecs:没实习非985211硕很难很难,只能说祝早日成功
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务