一道发源于游戏中的数列题(求项数最大值)

之前上高中的时候打游戏时想到的一道题目

一道发源于游戏中的数列题(求项数最大值)_第1张图片

扑克飞镖:每使用一次法力值消耗增加1点 初始法力值为零费 每次使用后回手

吹气:获得五点法力值 手牌中法力值最高的牌消耗归零

假设魔术师现在手中仅有上述两张手牌 且两张牌的配合机制如下: 当打出吹气后 扑克飞镖的法力值重新计算(即首项为零 公差为一的等差数列)

请问:(1).当魔术师初始法力值为25 求本回合中她最多可以打出几次“扑克飞镖”?

(2).当魔术师初始法力值为常数m时(m>0)求本回合中她最多可以打出几次“扑克飞镖”? (注:(1)与(2)中“吹气”必须打出)

当然,如果这道题要编程来解决的话,不妨直接做第二题好了。

我的思路:首先先确定下来如果不重置费用(也即不打出吹气)的情况下最多打出几次飞镖。这个可以用求根公式加高斯函数来算。然后对于每一种可能打出吹气的位置(也即大于等于0次,小于等于不打吹气的最大次数),计算该情况下的次数,并与已经出现的最大次数相比对。

代码如下

/*
扑克飞镖:每使用一次法力值消耗增加1点 初始法力值为零费
吹气:获得五点法力值 手牌中法力值最高的牌消耗归零
假设魔术师现在手中仅有上述两张手牌 且两张牌的配合机制如下:
当打出吹气后 扑克飞镖的法力值重新计算(即首项为零 公差为一的等差数列)
当魔术师初始法力值为正整数m时,求本回合中她最多可以打出几次“扑克飞镖”?


输入:一个合适的正整数     输出:最多打出扑克飞镖的次数
*/
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int N=scan.nextInt(),max=(int)((1+Math.sqrt(1+8*N))/2),cost=0,maxCount=0;
        //max是不打吹气的情况下最多打几次飞镖
        for(int i=0;i<=max;i++){//遍历每一种打出吹气的情况
            int count=0;//某种情况下的次数
            int temp=N;
            while(N>=cost){
                if(count==i){
                    cost=0;
                    N=N+5;
                    count++;//不写个count++这个if一直执行
                    continue;
                }
                N-=cost;
                count++;
                cost++;
            }
            if(count-1>maxCount){
                maxCount=count-1;
            }
            N=temp;
            cost=0;
        }
        System.out.print(maxCount);
    }
}

我觉得在自己的代码中涉及到一些比较丑陋的地方,首先是第23行的count++,如果不写这一句到了count加到i的时候就会一直执行这个if,导致死循环,所以只能先在这里给它加上,理解成现在打了几张牌,而吹气时有且仅有1张的,那么最后减1,就是打出飞镖的次数。

其次是N和cost在循环中不断改变,每次内循环结束后我只能加个存储器重新赋值。

最后是算法问题,两个循环嵌套会不会复杂度太高?有没有这个思路下更好的数学优化算法或者是其他思路和算法?感谢大家的交流和帮助!

你可能感兴趣的:(java,c++,c语言,python,算法)