Help is needed for Dexter(UVA

来源:互联网 发布:淘客网站源码建立 编辑:程序博客网 时间:2024/05/29 14:23

一、大概题意:

给个数字N,会出现从1到N的序列,要求每次从1-N中任选某个数字,从序列中任选某些数去减去该数字,直至序列中所有数字为0。



二、解题思路:

找寻规律可发现,N 为偶数时,其所需要的步骤等于  1 + (N为 N/2时所需要的步骤);N为奇数时,与其前一个偶数所需要的步骤相同。

特别注意:本题需要计算到1e9,但是开1维dp数组只能开到1e8,所以从1e8-1e9需要单独计算。



三、举例:

N = 3,序列:1 2 3   

所需最小步骤:①选则数字2,将序列中的2 -3减去该数字,此时序列中数字为0 1 1   

 ②选择数字1,将序列中的2个1减去该书组,此时序列中数字全部为0

N = 6,序列:1 2 3 4 5 6   

所需最小步骤:① 选则数字3,将序列中的3 -6减去该数字,此时序列中数字为0 1 1 2 2 3  (也可以将序列中的4 -6减去该数字,此时序列中数字为1 1 2 2 3 3 )

剩下所需步骤与n= 3相同

N = 7,序列:1 2 3 4 5 6  7 

所需最小步骤:① 选则数字4,将序列中的4 -7减去该数字,此时序列中数字为0 1 1 2 2 3 3 

剩下所需步骤与n= 3相同



四、附代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<stack>#include<queue>#include<cstring>#include<string>#include<set>#include<cmath>using namespace std;#define inf 0x3f3f3f3fconst int maxn = 1e8;typedef long long LL;int n;int dp[maxn];void Table(){    memset(dp,0,sizeof dp);    dp[1] = 1;    dp[2] = 2;    for(int i = 3; i <= maxn; ++i)    {        if(i % 2 == 1)        {            dp[i] = dp[i-1];        }        else{            dp[i] = 1 + dp[i / 2];        }    }}void See(){    for(int i = 1; i <= 100; ++i)    {        cout << dp[i] << " ";        if(i % 10 == 0){            cout << endl;        }    }    //134217728   28    //536870912   30    //268435456   29}int main(){    Table();    while(scanf("%d",&n) != EOF)    {        if(n <= 100000000)        {            printf("%d\n", dp[n]);        }        if(n > 100000000 && n < 134217728)        {            cout << 27 << endl;        }        else if(n >= 134217728 && n < 268435456)        {            cout << 28 << endl;        }        else if(n >= 268435456 && n < 536870912)        {            cout << 29 << endl;        }        else if(n >= 536870912)        {            cout << 30 << endl;        }    }}