A water problem 常数优化的故事。。

来源:互联网 发布:淘宝四川百灵鸟笼子 编辑:程序博客网 时间:2024/04/29 23:16

题目在这:http://dutacm.club:7217/codesheaven/problem.php?id=1089


正解是dp,分奇数偶数来考虑。

如果i是奇数,那么最优解由i-1加一以及(i+1)/2乘二减一构成

如果i是偶数,那么最优解由i-1加一以及i/2乘二构成

然后dp跑一遍就行了。


但是当时我看了数据范围和时限之后,觉得BFS就能过啊,就陷入了无尽的深渊。。。


一开始直接写了一个,自己弄的几个样例跑了5秒,交上去T了。



自然是不甘心的,于是开始了优化,第一步优化了搜索边界。还是T了。

于是开始开始剪枝,剪枝偶尔剪多了还会WA。。最后弄到了一个合理的范围,自己跑数据1s,交上去还是T了。


然后开始优化常数,开始用位运算来代替一些操作,同时优化一些if条件,最后还把quque换成了博客上手写的那个。

运行0.8s,交上去,还是T了。。当时比赛就结束了,,


第二天,看了题解之后写了个dp,运行才花了0.34秒



交上去AC了,发现用时3300MS!这样计算下来大概自测数据0.7s能过的话就能成功AC!


发现这一点后我十分激动。把cin全换成scanf,把Queue里面的错误输入判断全删掉,常用功能上了inline。。

测试运行0.64s!

十分兴奋地交上去,然后。。然后WA了。。去掉了一个奇怪的剪枝之后AC了!

常数优化了十倍。。终于用乱搞BFS把一个DP题给过了。。虽然数据水也是一部分原因,估计7s的时限也是为了卡乱搞。。不过我还是强行过了。。


这是赛后交的几次。。比赛中好像-17了。。



哈哈哈好鸡冻,贴上我的6sAC的代码:


#include <iostream>#include <queue>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime> using namespace std;const int maxn = 1e7+5;const int maxnn = maxn*1.4;const int minn = maxn*0.5;struct Queue  {      int f,r;      int *data;      int sz;      Queue(int x=1)      {          f=r=0;          sz=x;          data=new int[x];      }      inline int next(int x) {return (x+1)%sz;}      inline int pre(int x) {return (sz+x-1)%sz;}      inline void push(int x)      {            data[r]=x;          r=next(r);      }      int front()      {          if(f==r) cout<<"Error!Empty!"<<endl;          return data[f];      }      inline void pop()      {          f=next(f);      }      bool empty(){return f==r;}  };  long long cost[maxnn];Queue u(minn);int main(){//freopen("in.txt","r",stdin);long long n,x,y;while(~scanf("%lld%lld%lld",&n,&x,&y)){//int t=clock();if(n*x <= 2*y || n==1){cout<<n*x<<endl;continue;}memset(cost,-1,sizeof(cost));cost[0]=0;cost[1]=x;u.push(1);int div=y/x;int up=n*2/3;int lo=n;while(lo>=4) lo=lo>>1;lo=lo&1;while(!u.empty()){int now=u.front();u.pop();/*if(div<2 && now>=17 && now<=50 ){int temp=now;while(temp>=4) temp=temp>>1;temp=temp&1;if(temp!=lo) continue;}*/if(!(now&1) && ((cost[now-1]==-1) || (cost[now] + x < cost[now-1]))){ cost[now-1]=cost[now]+x;u.push(now-1);}if(    now < n && (cost[now+1]==-1) || (cost[now] + x < cost[now+1])){cost[now+1]=cost[now]+x;u.push(now+1);}if(now>=div && now <= up+1 && ((cost[now<<1]==-1) || (cost[now] + y < cost[now<<1]))){cost[now<<1]=cost[now]+y;u.push(now<<1);}}printf("%lld\n",cost[n]);//cout<<clock()-t<<endl;}}




0 0
原创粉丝点击