求构成给定自然数的平方数的最小个数

数学定理解决DP问题
本文探讨了如何通过数学定理解决动态规划问题,并详细解释了四平方定理的应用。

想了很久啊,看了标签是 DP,所以考虑之后自己琢磨出了个策略,结果还是不对啊,各种 test case 过不去。

后来才发现这其实还可以用更为简单的方法——数学定理

对没错,所以说世界上只有两种程序员:懂数学的和不懂数学的。

// 四平方定理,又称 Lagrange's four-square theorem,
// 大意是,对于任意自然数,都可以表示为不多于四个平方数的和.
int numSquares(int n)
{
    // 因子包含 4 的数在除 4 后,不影响其包含的平方数的个数.
    while(n % 4 == 0){
        n /= 4;
    }
    
    // 可被分解成形式为 4^a * (8 * b + 7) 的数,包含的平方数个数为 4.
    if (n % 8 == 7){
        return 4;
    }
    
    // 寻找一个数,使 n 与其平方的差是一个平方数.
    for(int factor = 0;;++factor){
        auto square = factor * factor;
        // 若其平方已大于 n,则停止搜索.
        if (square > n){
            break;
        }
        
        auto possibleFactor = static_cast<int>(sqrt(n - square));
        if (possibleFactor * possibleFactor + square == n){
            // 若 factor 为零,则 n 本身就是平方数,故返回 1.
            return factor == 0? 1 : 2;
        }
    }
    // 若以上条件均不满足,则 n 必然由三个平方数构成。
    return 3;
}

 

 

转载于:https://www.cnblogs.com/wuOverflow/p/4811367.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值