ZOJ1937:Addition Chains——题解

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1937

题目大意:创造一个数列,使得它:

1.单调不递减。

2.其中一个元素一定存在其前面两个元素之和与它相等。

3.开头为1,结尾为n。

求一个这样的最短数列。

——————————————————————————————————

IDA*一定的(n<=100)

对于IDA*是什么不了解的,可以看我的置顶骑士精神那道题。

我们的估价函数就是当前的值翻多少次二倍后能得到n。

显然假设当前的值为i,则答案为log2(n/i)。

然后就是和普通的IDA*一样做了。

(第1条不要忘了,我就是被这样坑过TAT)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<cmath>
using namespace std;
int n,ans,a[5001];
inline int h(int step){
    if(a[step]==n)return -1;
    return log(n/a[step])/log(2);
}
inline bool dfs(int step){
    if(step==ans){
    if(h(step)==-1)return 1;
    return 0;
    }
    if(h(step)+step>ans)return 0;
    for(int i=step;i>=1;i--){
    for(int j=i;j>=1;j--){
        if(a[i]+a[j]>n||a[i]+a[j]<a[step])continue;
        a[step+1]=a[i]+a[j];
        if(dfs(step+1))return 1;
    }
    }
    return 0;
}
int main(){
    a[1]=1;
    while(scanf("%d",&n)!=EOF&&n){
    for(ans=1;;ans++){
        if(dfs(1))break;
    }
    printf("%d",a[1]);
    for(int i=2;i<=ans;i++)printf(" %d",a[i]);
    printf("\n");
    }
    return 0;
}
时间: 2024-11-07 18:54:46

ZOJ1937:Addition Chains——题解的相关文章

POJ2248 Addition Chains

Addition Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5273   Accepted: 2833   Special Judge Description An addition chain for n is an integer sequence with the following four properties: a0 = 1 am = n a0 < a1 < a2 < ... <

poj2248 Addition Chains 迭代加深搜索

Addition Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5454   Accepted: 2923   Special Judge Description An addition chain for n is an integer sequence <a0, a1,a2,...,am="">with the following four properties: a0 = 1 a

UVa 818 Cutting Chains 题解

难度:β 建议用时:40 min 这题应该有迭代加深搜索的解法的,但我参考网友做法,用暴力枚举法. 大致思路是:枚举圆环的每种开闭状态,统计符合要求的最小的打开的圆环的数量. 要判断打开圆环的某一种方法是否符合要求,容易想到的一个是先判断除去这些已打开的圆环外的闭合圆环有没有组成一个环. 如果还有环,那么无论把打开的圆环怎样重新连城一条链套回去,都不能消除环,而题目要求我们够一条链.所以如果任然存在环的方法是不行的. 0000   0 (此时还有一个环没打开,不能组成链) 0    0 0000

POJ 2248 Addition Chains dfs(水)

题意:给出n 构成出满足下列条件 长度最小的数列a[0]=1,a[m]=n, a[0]<a[1]<..<a[m]每个下标k都存在(i,j<k) 满足:a[k]=a[i]+a[j] n<=100 枚举长度 dfs爆搜+剪枝 水过, #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N=2e5+20; int n,a[N

POJ3421:X-factor Chains——题解

http://poj.org/problem?id=3421 题目大意:一个数列,起始为1,终止为一给定数X,满足Xi < Xi+1 并且Xi | Xi+1. 求出数列最大长度和该长度下的情况数. —————————————— 很简单想到分解X质因数,这样我们每加一个数就是前一个数*其中一个质因数即可. 所以长度为质因数个数. 至于情况数,就是有重复的排列数,去重即可求. (不开longlong见祖宗,十年OI一场空) #include<cstdio> #include<cstri

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 ,找出符合上述四个条件的长度最小的整数加成序列. 如果有多个满足要求的答案,只需要

POJ 2245 Addition Chains(算竞进阶习题)

迭代加深dfs 每次控制序列的长度,依次加深搜索 有几个剪枝: 优化搜索顺序,从大往下枚举i, j这样能够让序列中的数尽快逼近n 对于不同i,j和可能是相等的,在枚举的时候用过的数肯定不会再被填上所以可以去重(记得回溯) #include <iostream> #include <cstring> #include <cstdio> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; inl

C++解题报告 : 迭代加深搜索之 ZOJ 1937 Addition Chains

此题不难,主要思路便是IDDFS(迭代加深搜索),关键在于优化. 一个IDDFS的简单介绍,没有了解的同学可以看看: https://www.cnblogs.com/MisakaMKT/articles/10767945.html 我们可以这么想,设当前规定长度为M,题目要求得出的数为N. 在搜索中,当前的步数为step,当前的数列为 数组a. 首先来确定思路,便是在以得出的数列a中枚举每两个数相加得出sum,然后继续搜索下一步. 初步的代码便是: void iddfs(int x) { for

POJ2248 Addition Chains 迭代加深

不知蓝书的标程在说什么,,,,于是自己想了一下...发现自己的代码短的一批... 限制搜索深度+枚举时从大往小枚举,以更接近n+bool判重,避免重复搜索 #include<cstdio> #include<iostream> #include<cstring> #define R register int using namespace std; inline int g() { R ret=0; register char ch; while(!isdigit(ch