zoukankan      html  css  js  c++  java
  • UVA529 Addition Chains


    题意:

    一个与 nn 有关的整数加成序列 $<a_0,a_1,a_2,...,a_m>$ 满足以下四个条件:
    1.$a_0=1$

    2.$a_m=n$
    3.$a_0<a_1<a_2<...<a_{m-1}<a_m$
    4. 对于每一个 k(1≤k≤m) 都存在有两个整数 i 和 j(0≤i,j≤k-1,i和 j 可以相等 ) ,使得 $a_k=a_i+a_j$​
    你的任务是:给定一个整数 nn ,找出符合上述四个条件的长度最小的整数加成序列。

    如果有多个满足要求的答案,只需要输出任意一个解即可。
    举个例子,序列<1,2,3,5> 和 <1,2,4,5> 均为 n=5 时的解。

    一看就是搜索,于是爆搜。。。

    然而,这是个迭代加深搜索。。。

    剪枝如下:


    1.优化搜索顺序
    显然倒序枚举更有可能得到可行解。

    让数大一些,尽可能接近n;

    2.排除不可行解
    我们发现,对于加成数列的要求还有一个,即 $a_m=n$

    假设当前已经通过枚举得出了 $a_i$ ,正准备搜索第 i+1 个数。

    考虑通过当前形势下到第 m 项可以得到的最大值,显然,$max(a_{i+1})=a_i+a_i=2×a_i$​

    $max(a_{i+2})=a_{i+1}+a_{i+1}=2×a_{i+1}=4×a_i=2^2×a_i$​

    故由递推可得

    $max(a_m)=2^{m-i}×a_i$​

    所以在进行对 i+1 个数的搜索前,计算一下 $max(a_m)$ 是否可以达到 n ,

    如果达不到则无需进行下一步的搜索。

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define love_nmr 0
    int n;
    bool flag;
    int ans[10050];
    int maxx;
    inline void print()
    {
        for(int i=1;i<maxx;i++)
            printf("%d ",ans[i]);
        printf("%d
    ",ans[maxx]);
    }
    inline void dfs(int depth,int pos)
    {
        if(depth==maxx+1)
        {
            if(ans[maxx]==n)
                flag=true;
            return;    
        }
        for(int i=depth-1;i>=pos;i--)
        {
            for(int j=i;j>=1;j--)
            {
               int f=ans[depth]=ans[i]+ans[j];
               for(int is=pos+1;is<=maxx;is++) f<<=1;
               if(f<n)break;
               dfs(depth+1,i+1);
               if(flag)return;
               ans[depth]=0;
            }
        }
    }
    int main()
    {
        while(~scanf("%d",&n)&&n)
        {
            if(n==1)
            {
                printf("1
    ");
                continue;
            }
            flag=false;
            ans[1]=1;
            for(int i=2;i<=n;i++)
            {
                maxx=i;
                dfs(2,1);
                if(flag)
                {
                    print();
                    break;
                }
            }
        }
    }
  • 相关阅读:
    查看Eclipse版本号的方法
    设置Eclipse的字体风格方式
    又遇两个小异常
    我所推崇的三种心态
    关于javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in &lt;forEach&gt;
    Http请求中Content-Type讲解
    ftp实现文件上传(下载)
    解析html文档的java库及范例
    xslt循环转换子元素
    XPath学习:轴(1)——child
  • 原文地址:https://www.cnblogs.com/olinr/p/9429690.html
Copyright © 2011-2022 走看看