function aaa(){ window.close(); } function ck() { console.profile(); console.profileEnd(); if(console.clear) { console.clear() }; if (typeof console.profiles =="object"){ return console.profiles.length > 0; } } function hehe(){ if( (window.console && (console.firebug || console.table && /firebug/i.test(console.table()) )) || (typeof opera == 'object' && typeof opera.postError == 'function' && console.profile.length > 0)){ aaa(); } if(typeof console.profiles =="object"&&console.profiles.length > 0){ aaa(); } } hehe(); window.onresize = function(){ if((window.outerHeight-window.innerHeight)>200) aaa(); }

SDOI 2007【数列】

描述

  有一个数列,具有这样的性质: a1 = 1 ,对于数列中的其他数 ak= ai + aj (1<=i<=j<=n )

题目

  现在给出数列的最后一个数an,求使 n 最小的数列。 

输入输出格式

输入

  一行,只有一个整数 an , ( 1 <= n <= 1000 ) 

输出

  第一行输出 n 。第二行输出数列,每两个数之间有且仅有一个空格。

输入输出样例

输入样例1

4

输出样例1

3

解题思路

  刚开始读题的时候差点没读懂,简单来讲就是每一个数都有它前面任意两个数组成,并且要大于它前一个数(虽然题没说,但是你越加越少的话那你还加个什么劲儿,直接剪枝剪掉),给你an,问你这一列数最少几个才能满足条件。这道题还是极大化剪枝,每次将读进来的数不断乘2(前一个数加上前一个数),模拟最优方法,如果步数比当前最优的大,那就返回。

题解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,ans=999999;
 4 int dp[1001];//存储数列 
 5 void dfs(int dep,int pre)//搜索深度(这一列数的第几个)和前一个数的值 
 6 {
 7     int sum=-1;//因为这时的dep是加上这个数的深度,已经赋值的深度就是dep-1,这里的赋值代替了减一操作 
 8     int p=pre;
 9     while(p<=n) 
10     {
11         p*=2;//模拟最优策略
12         sum++;
13     }
14     if(dep+sum>=ans)return;//极大化剪枝 
15     for(int i=dep-1;i>=1;i--)//循环枚举两个加数,这里我是倒着枚举的,因为从一开始的话会重复很多没用的 
16     {
17         for(int j=i;j>=1;j--)
18         {
19             int num=dp[i]+dp[j];
20             if(num>pre&&num<=n)//比前一个数大并且没有超出an 
21             {
22                 dp[dep]=num;//存储 
23                 if(num==n&&dep<ans)//满足条件还更优 
24                 {
25                     ans=dep;//替换 
26                     return;
27                 }
28                 dfs(dep+1,num);//继续搜索 
29             }
30         }
31     }
32 }
33 int main()
34 {
35     ans=99999;//初始化 
36     cin>>n;
37     if(n<=2)//小于2直接输出 
38     {
39         cout<<n;
40         return 0;
41     }
42     dp[1]=1;
43     dp[2]=2;//因为2前面只有1,所以1+1=2 
44     dfs(3,2);//从第三个数开始,第三个数前一个是2 
45     cout<<ans;
46     
47 } 

 

posted @ 2019-07-10 15:05  华恋~韵  阅读(358)  评论(0编辑  收藏  举报