hdu-5587 Array(回溯)

题目链接:

Array

Time Limit: 2000/1000 MS (Java/Others)   

 Memory Limit: 131072/131072 K (Java/Others)

Problem Description

Vicky is a magician who loves math. She has great power in copying and creating.
One day she gets an array {1}。 After that, every day she copies all the numbers in the arrays she has, and puts them into the tail of the array, with a signle ‘0‘ to separat.
Vicky wants to make difference. So every number which is made today (include the 0) will be plused by one.
Vicky wonders after 100 days, what is the sum of the first M numbers.

Input

There are multiple test cases.
First line contains a single integer T, means the number of test cases.(1≤T≤2∗103)
Next T line contains, each line contains one interger M. (1≤M≤1016)

Output

For each test case,output the answer in a line.

Sample Input

3

1

3

5

Sample Output

1

4

7

题意:

一开始有一个1,每次操作都把这个数字串复制并且在前边加上一个0,然后再把得到的这个串的每个数字都加1,然后再把这个新得到的数字串加到原来串的末尾,问前m位数的和是多少;

思路:

找规律的题,先初始化,第i次操作一次得到的和为dp[i],长度为L[i],转移方程看代码;然后对一个数m,找到最大的j,L[j]<=m的长度串,ans+=dp[j],ans+=m-L[j];

m减去这个长度L[j]并去掉前导0,得到一个新的更小的m,这样回溯最后就能得到答案了;

AC代码:

//#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;j<=n;j++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());
    for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + ‘0‘);
    putchar(‘\n‘);
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const LL inf=1e14;
const int N=1e4+15;
const int maxn=18;

LL dp[70],L[70],ans,sum[70];
void Init()
{
    dp[1]=1;
    L[1]=1;
    for(int i=2;i<70;++i)
    {
        dp[i]=2*dp[i-1]+L[i-1]+1;
        L[i]=2*L[i-1]+1;
    }
}

void dfs(LL x)
{
    if(x<=0)return;
    for(int i=1;i<70;i++)
    {
        if(L[i]<=x&&L[i+1]>x)
        {
            ans+=dp[i];
            x-=L[i]+1;
            ans+=x+1;
            break;
        }
    }
    dfs(x);
}
int main()
{
    int  t;
    read(t);
    LL m;
    Init();
    while(t--)
    {
        ans=0;
        read(m);
        dfs(m);
        printf("%lld\n",ans);
    }

        return 0;
}
时间: 2024-10-15 17:33:46

hdu-5587 Array(回溯)的相关文章

hdu 5587 Array 数学题

Array Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5587 Description Vicky is a magician who loves math. She has great power in copying and creating.One day she gets an array {1}. After that, every day she cop

HDU 5587——Array——————【规律】

Array Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 417    Accepted Submission(s): 211 Problem Description Vicky is a magician who loves math. She has great power in copying and creating.One

HDU 1015 dfs回溯

题目真长.....看了好长时间才看懂.. 就是给你一个32位数字和一个最多15个字符的字符串,从字符串中选出5个字符,若满足题中给的那个式子,输出字典序最大的那5个字符,若不满足,输出no solution. 为了解决字典序问题,在输入字符串后,把字符串按从大到小排一下序,搜索一下若满足条件输出即可. 贴代码. 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <

hdu 6197 array array array

http://acm.hdu.edu.cn/showproblem.php?pid=6197 题意:给你一个数组 然后给你一个k  让你从数组里面剔除k个数  使得剩余的数组 是 单调非递减  或 单调非递增的 判断可不可能 思路 : 直接写LIS  然后判断 n-k 和 LIS 长度的大小关系 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+100; const int INF = 0x3f3f3f3f; i

HDU 6197 array array array 2017沈阳网络赛 LIS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6197 题意:给你n个数,问让你从中删掉k个数后(k<=n),是否能使剩下的序列为非递减或者非递增序列 解法:签到题,就是让你求最长不下降子序列长度len,然后判断下n-len是否小于k(将序列反着存下来然后再求即最长不上升子序列,取两者len中的较大值),然后直接套nlogn的模板即可. #include <bits/stdc++.h> using namespace std; const

HDU - 6197 array array array (最长上升子序列&amp;最长下降子序列)

题意:对于一个序列,要求去掉正好K个数字,若能使其成为不上升子序列或不下降子序列,则“A is a magic array.”,否则"A is not a magic array.\n". 分析: 1.求一遍LCS,然后在将序列逆转,求一遍LCS,分别可得最长上升子序列和最长下降子序列的长度tmp1.tmp2. 2.n - tmp1 <= k或n - tmp2 <= k即可,需要去掉的去完之后,在已经是最长上升或最长下降的序列中随便去够k个就好了. #include<

第十场 hdu 6172 Array Challenge(矩阵快速幂)

http://acm.hdu.edu.cn/showproblem.php?pid=6172 题目大意:按照给出的公式算出an 解题思路:an=4an-1+17an-2-12an-3,不要问我为什么,我也不知道(?_?) AC代码: 1 #include <iostream> 2 #include<bits/stdc++.h> 3 //if(~i)//当i不是-1时满足条件 4 using namespace std; 5 const int SMod=1e9+7; 6 struc

hdu 4155 dfs回溯

数据并不大,dfs回溯即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 30; 7 char str[N]; 8 int digit[N]; 9 10 int dfs( int sum ) 11 { 12 if ( sum > 31 ) return 1; 13 for ( int i = 1; i

2017多校第10场 HDU 6172 Array Challenge 猜公式,矩阵幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6172 题意:如题. 解法: #include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 1e9+7; struct Matrix{ LL a[3][3]; void set1(){ memset(a, 0, sizeof(a)); } void set2(){ memset(a, 0, siz