4174:皇家棋神(C++)

题目描述

看到下图,拥有QQ宠物的同学对下图一定不会陌生,没错这就是QQ宠物皇家战棋。自从2009元旦前夕腾讯推出该款游戏,迅速成为热门游戏,不仅仅因为其可爱的造型,更有元宝和蓝钻的诱惑。

小明为了给自己的宠物赚取足够的生活费,也加入了激烈的角逐。由于战术运用得当,加上些许的运气,小明屡战屡胜。转眼间,时间过去了2个月,小明也成为了名副其实的万元户+大城主,宠物也衣食无忧。

而此时的玩家,都已具备了一定的战术经验,小明也占不到丝毫便宜,大多数时候只能靠运气取胜,此时皇家战棋也变得索然无味。于是小明开始思考另外一个有趣的问题,若是每个战棋能自我成长,又能训练新兵,那一定很有意思。

有一天,在一个毫无防备力量的城邦,诞生了一名划时代的领袖(当然他也是从士兵做起)每过一个时刻,任何一个作战单位的战斗力就会提升一分,而每个作战单位在提升力量的同时,又会培养一名新兵作为下属,每个作战单位所能拥有的下属数量上限为k。小明很想知道,在给定下属上限数量k的情况下,第n个时刻该城邦所具有的总战斗力。

在k=2,n=5时情况如下:
 


 


 

在第5个时刻,城邦的领袖,已经蜕变为将军,而整个军队的战斗力也从第1个时刻的1,变为26。而随着军队战斗力与部队数量的增加,城邦已经有足够的力量抵御外敌,城邦的战斗力在到达或者超过1234567890之后,每个战斗单位的战斗力将不再增加,也不再训练新兵。

小明想要知道,在第n时刻,每个单位最大下属数量为k时,城邦的战斗力。

输入格式

输入文件名为cheese.in。

第一行包含2个整数n和k,1<=n,k<=2^32-1。

k>=0

输出格式

输出文件cheese.out共1行,第n时刻城邦所具有的总战斗力。

样例输入content_copy

5 2

样例输出content_copy

26

提示/说明

【数据范围】

30%的数据 0<= k <=3 , n<=300

100%的数据1<=n,k<=2^32-1

思路

        这道题的图乍一眼看过去感觉是二叉树,等仔细看完题以后发现只是图长得像而已。以样例条件为例,求第i个时候的总战斗力,其实就等于i+第i-1时候战斗力+第i-2时候战斗力,公式其实就是f[i]=i+f[i-1]+f[i-2]。

        我当初以为到这就完了,写个递归一试,直接大错特错。定睛一看,忘了训练的新兵数是可变换的,于是就得用递推了,更新后的公式是f[i]=i+f[i-1]+f[i-2]+...+f[i-k]。但如果i-k<0,就从0开始。

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxx = 1234567890;
const ll N = 1e5 + 10;
ll i, k, dp[N], ans;
ll dg(ll n, ll m)
{
    ll p = 0;
    if (m < 0) {
        m = 0;
    }
    for (int j = m; j <= n; j++) {
        p += dp[j];
    }
    return p;
}
int main() {  
    cin >> i >> k;
    if (k == 0) {//特判,k为0的情况
        if (i < maxx) {
            cout << i;
            return 0;
        }
        else {
            cout << maxx;
            return 0;
        }
    }
    dp[1] = 1;//初始条件
    for (int j = 2; j <= i; j++) {
        dp[j] = dg(j, j - k) + j;//转移方程式
        if (dp[j] >= maxx) {//判断战力是否达到上限
            ans = dp[j];
            break;
        }
        ans = dp[j];//更新战力
    }
    cout << ans;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值