您的位置:首页 > 其它

SDUT 3322 (收索+打表)

2015-09-17 19:26 411 查看

题目描述

一下迭代序列定义在整数集合上:
n = n/2 (n 是偶数)
n = n*3 + 1(n 是奇数)
应用以上规则,并且以数字13开始我们得到一下序列:
13,40,20,10,5,16,8,4,2,1
可以看出这个以13开始以1结束的序列一共经过了9次运算。虽然还没有被证明(Collatz问题),但是人们认为在这个规则下,以任何数字开始都会以1 结束。

以哪个不超过x的正整数开始,能得到运算次数最多的序列?
注意:一旦序列开始,也就是从第二项开始,项是可以超过x的。

输入

输了一个整数n,接下来n行,每行一个整数x (1 <=x<=1,000,000)。

输出

对于每次询问,你需要计算出最多的运算次数是多少。为了节约输出时间,你只需要输出所有询问的答案之和 。

示例输入

3
1
2
3


示例输出

8


看到此题的优化方式首先反应的是打表,但是打表仍然不够

思路: 边打表边收索.是为了减枝,并找到当前步数的最大值.

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#define ll long long
#define MAX 1000010
using namespace std;
ll dp[1000010],a[1000010];
inline void read(int& x)
{   char ch;
    while (!((((ch=getchar())>='0') && (ch <= '9')) || (ch == '-')));
    x = ch-'0';
    while (((ch=getchar())>='0') && (ch <= '9')) x = x*10+ch-'0';
}
ll DFS(ll i)
{
    if(i==1)
    {
        return 0;
    }
    if(i<1000000)
    {
        if(a[i])
            return a[i];
    }
    if((i&1)==0)
    {
        return DFS(i/2)+1;
    }
    if((i&1)==1)
    {
        return DFS(3*i+1)+1;
    }
}
int main()
{
    int n,k;
    ll ma=0,m;
    for(int i=1;i<=1000000;i++)
    {
        a[i]=DFS(i);
        if(ma<a[i])
            ma=a[i];
        dp[i]=ma;
    }
    read(k);
    ll ans=0;
    while(k--)
    {
        read(n);
        ans+=dp
;
    }
    printf("%lld\n",ans);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: