bzoj 4428: [Nwerc2015]Debugging

题目链接:Debugging(cf上链接)

题目大意:(援引大佬博客的翻译和题解)

你看中的调试器将不会在这件事上帮助你。有代码可以通过多种方式在调试与正式发布的间隙发生不同的行为,当出现这种情况,我们可能不得不求助于更原始的调试方式。

所以,你和你的printf现在在寻求一行导致该发布版本崩溃的代码。幸运的是:增加printf语句到程序里,既不会制造bug(仍然崩溃在同一原始的代码行),也没有影响执行时间(至少不显著)。 因此,即使在每行前加一个printf语句,运行程序,直到它崩溃,并检查最后打印行。

然而,它需要一些时间来添加每个printf语句到代码,并且该程序可以具有很多行。

因此,把一个printf语句在程序的中间或许是一个更好的计划,让它运行,观察它是否在加入行前崩溃,然后继续在代码的前一或后一半寻找。

不过话又说回来,运行程序可能需要很多时间,所以时效最优的策略可能是介于两者之间。

编写计算最坏情况下的最小时间来寻找崩溃行(无论它在哪里),认为你选择最优的加printf语句策略。

我们在5小时内发布新的版本,所以这个问题十分严重,需要尽快解决。

输入包括一行三个整数: 
n(1≤n≤10^6),代码行的数目; 
r(1≤r≤10^9),编译和运行程序直到它崩溃的时间量; 
p(1≤p≤10^9),增加单个的printf行所花费的时间。 
您已经运行一次程序,因此已经知道它崩溃的地方。 
Output

输出的最坏情况使用最优策略找到崩溃行的时间。 
Sample Input

Sample Input 1

1 100 20

Sample Input 2

10 10 1

Sample Input 3

16 1 10 
Sample Output

Sample Output 1

0

Sample Output 2

19

Sample Output 3

44

题解:

è¿éåå¾çæè¿°

官方题解说记忆化搜索是O(nlogn)的 
但是看了看Claris题解说是O(n\sqrt{n})
感觉Claris的分析是对的啊..不知道官方题解是怎么来的

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
typedef long long ll;
using namespace std;
#define INF 0x3f3f3f3f
const int mod=1e9+7;
const int maxn=1e6+10;
int n, r, p;
ll dp[maxn];
ll dfs(int x) {
	if(x <= 1) return 0;
	if(dp[x]) return dp[x];
	ll res = (ll)(x - 1) * p;
	for(int i =2;i<x; i=ceil((double)x/(ceil((double)x/i) - 1)))
		res = min(res,(ll)(i-1)*p+dfs(ceil((double)x/i)));
	return dp[x] = res + r;
}
int main() {
	while(~scanf("%d%d%d",&n,&r,&p)){
		memset(dp,0,sizeof(dp));
		printf("%I64d\n", dfs(n));
	}
	return 0;
}

============================================分割线===============================================

这道题目需要注意分块思想的应用和取整运算的写法。尤其这一步对i的赋值是一个小技巧:x = (n - 1) / ((n - 1) / i) + 1。

for(int i =2;i<x; i=ceil((double)x/(ceil((double)x/i) - 1)))

 

具体取整方面的证明可以参考具体数学。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值