• n点游戏


    n点游戏

    24点游戏是非常经典而简单的小游戏,从一堆扑克牌中抽取4张,向其中添加运算符号并使其运行结果恰等于24,这叫作24点游戏。

    现在我们不再是组合24,而是组合出给定的数字n,但要求只可以利用任意多个数字1,并且运算只有加法、乘法和括号。对于给定的数字N,最少需要几个1可以完成

    数据输入

    输入一个数字N( 1≤N≤5000)

    数据输出

    输出一个整数,表示仅用加号,乘号和括号能组成等于N所需最少的1的个数

    样例1
    输入样例
    7
    输出样例
    6
    提示
    7=(1+1)*(1+1+1)+1
    样例2
    输入样例
    27

    输出样例
    9

    提示
    27=(1+1+1)(1+1+1)(1+1+1)

    思路

    一维的动态规划。
    若用f(n)表示计算n所需最少1的个数,对于n=1-5的情形,f(n)=n。
    举几个例子,n=6时,6=23,所以f(6)=f(2)+f(3)=5,对于n=9,由于9=33,所以f(9)=f(3)+f(3),要计算f(27),因为27=39,所以f(27)=f(3)+f(9),但计算f(9)还要计算f(9)=f(3)f(3),这样计算的话会出现许多重复,刚才f(9)已经计算出来了,我们可以直接将其保存下来,将f()改为数组d[],从1开始向N计算d[i]的值即可。对于任何数字i>1,d[i]=d[i-1]+1,然后我们再检查是否有两个数字x,y相乘等于i,若有就尝试d[x]+d[y]是否小于当前d[i],若小于就更新d[i]。计算d[i]后依照此法再计算d[i+1],直到计算出d[N].

    代码

    #include <cstdio>
    #include <algorithm>
    #define MAXN 5007
    using std::min;
    
    
    int main(void)
    {
         int i,j,N;
         int dp[MAXN];
         scanf("%d",&N);
         dp[1]=1;
         for(i=2;i<=N;i++) 
         {
             dp[i]=dp[i-1]+1;//置初始的可能 
             for(j=2;j*j<=i;j++)//开方乘法,这个从质数的考察常见 
             {
                 if(i%j==0)//寻找乘法组合 
                 {
                     dp[i]=min(dp[i],dp[i/j]+dp[j]);//如果有乘法组合,那么更新 
                 }
             }
         }
         printf("%d
    ",dp[N]);
         return 0;
    }
    
  • 相关阅读:
    random模块的随机变换
    re模块与正则表达式进阶
    面向对象整体细化
    __new__内部工作方式
    前端之CSS
    前端之HTML
    数据库
    同步异步阻塞非阻塞
    进程间的通信
    day 36(多进程)
  • 原文地址:https://www.cnblogs.com/lingr7/p/10523744.html
Copyright © 2020-2023  润新知