码迷,mamicode.com
首页 > 其他好文 > 详细

codevs 2541 幂运算(迭代加深搜索)

时间:2016-06-10 20:18:31      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

/*
一开始想到了简单的深搜 维护当前可用的mi数组
然后回溯用哪个 不断更新新产生的mi
这样的问题是 由于mi不断产生 搜索规模扩大 
不好 不好  下面是奇丑的WA掉的代码 做个反面教材 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,ans=0x3f3f3f3f,f[1055],s[1055],top,vis[1055];
void Dfs(int p,int c)
{
    if(p<=0||p>n*2)return;
    if(f[p]==0)s[++top]=p,f[p]=1;
    if(p==n){ans=min(ans,c);return;}
    if(c>ans)return;
    for(int i=1;i<=top;i++)
      if(vis[i]==0)
        {
          vis[i]=1;
          Dfs(p+s[i],c+1);
          Dfs(p-s[i],c+1);
          vis[i]=0;
        }
}
int main()
{
    scanf("%d",&n);
    ans=n;
    Dfs(1,0);
    printf("%d\n",ans);
    return 0;
}
/*
正解是迭代加深
对于每次的搜索 我们限制最多能做几次运算 
这样搜索的规模就大大减小 
同样的维护已经得到的mi数组
数组的大小对应做了几次运算 
加上几个剪枝:
如果mi中最大的<<(limit-k)都到不了n 搜索失败
生成新的mi的时候 尽量组合数大的 这样也可以减小规模 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 20
using namespace std;
int n,a[N*2];
bool Dfs(int k,int limit)
{
    if(a[k]==n)return 1;
    if(k==limit)return 0;
    int maxx=0;
    for(int i=0;i<=k;i++)maxx=max(maxx,a[k]);
    if(maxx<<(limit-k)<n)return 0;
    for(int i=k;i>=0;i--)
      {
          a[k+1]=a[i]+a[k];
          if(Dfs(k+1,limit))return 1;
          a[k+1]=a[k]-a[i];
          if(Dfs(k+1,limit))return 1;
      }
    return 0;
}
int find()
{
    if(n==1)return 0;
    a[0]=1;
    for(int i=1;i<=N;i++)
      if(Dfs(0,i))return i;
}
int main()
{
    scanf("%d",&n);
    printf("%d\n",find());
    return 0;
}

 

codevs 2541 幂运算(迭代加深搜索)

标签:

原文地址:http://www.cnblogs.com/yanlifneg/p/5574134.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!