博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
279. Perfect Squares
阅读量:5322 次
发布时间:2019-06-14

本文共 2405 字,大约阅读时间需要 8 分钟。

最后更新

三刷

16-Jan-2017

数学题= = 加一点点动态规划。

dp[n]表示 N能分成的最小数量。。

然后无非就是看一个数怎么分= =拿12来说:

9+3 1 + dp[3]
...
4+8 1 + dp[8]
...
1+11 1 + dp[11]

看哪个最少就是哪个分完就保存一下,以后再利用。

Time: O(n²)

Space: O(n)

public class Solution {    public int numSquares(int n) {        int[] dp = new int[n+1];        dp[0] = 0;                for (int i = 1; i <= n; i++) {            dp[i] = Integer.MAX_VALUE;            for (int j = 1; j * j <= i; j++) {                dp[i] = Math.min(dp[i], dp[i-j*j] + 1);            }        }                return dp[n];    }}

一刷

给个N,计算N最少能由几个平方数组成

12 = 4 + 4 + 4 3个

13 = 4 + 9 2个

用DP来做

DP[N]代表 N最少由几个平方数组成

先看 N - M² > 0 ?

代表 DP[N]的值 = DP[N - M²] + 1
其中+1的1代表 最后要+的一个平方数M²
(N - M²) + M² = N
DP[N-M²]在1 TO N的过程中已经计算了

然后我们M+1

看看N是否可以减去一个更大的平方数

如果N - (M+1)² > 0

代表 DP[N]的值 = DP[N-(M+1)] + 1

但是我们不确定DP[N-(M+1)²]和DP[N-M²]谁大

所以要记录一个TEMP值 保留最小

public class Solution {    public int numSquares(int n) {         int[] dp = new int[n+1];        dp[0] = 0;        for(int m = 1; m <= n;m++)        {               dp[m] = Integer.MAX_VALUE;            //n - 1*1 > 0?            //n - 2*2 > 0?            //n - 3*3 > 0?            for(int t = 1; (m - t*t)>=0;t++)            {                dp[m] = Math.min(dp[m],dp[m-t*t]+1);            }            //System.out.println(dp[m]);                    }        return dp[n];    }}

---


二刷依然一头雾水,这个jianchao.li.fighter的题普遍数学味很大,头痛啊。。

public class Solution {    public int numSquares(int n)     {                /*        1       1        2       1 1         3       1 1 1        4       2 2        5       4 1        6       4 1 1        7       4 1 1 1        8       4 4        9       9        10      9 1        11      9 1 1        12      4 4 4        13      9 4        */                int[] dp = new int[n+1];                dp[0] = 0;                for(int i = 1; i <= n; i++)        {            dp[i] = Integer.MAX_VALUE;            for(int t = 1; t*t <= i;t++)            {                dp[i] = Math.min(dp[i],dp[i-t*t]+1);            }        }                return dp[n];            }}

其实说白了就是分解一个int为所有平方的和,怎么分数量最少。

在一开始分解的过程中就看出来了,12我分的是9+1+1+1 总共4个

而结果是 4+4+4 总共3个

暴力法就是 所有可能性都试一次,比如先从最大的平方和分:

9 1 1 1
4 4 4
4 4 1 1 1 1
4 1 1 1 1 1 1 1 1 1
这种,有很多重复计算。想办法减少重复计算。那么就是DP了。
dp[n]表示分解n的最优解。

dp[i] = Math.min(dp[i],dp[i-t*t]+1);

这样刚才的暴力分解就变成了个

9+3 1 + dp[3]
4+8 1 + dp[8]
1+11 1 + dp[11]

省去了很多重复计算。

转载于:https://www.cnblogs.com/reboot329/p/6291624.html

你可能感兴趣的文章
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>
Centos7.2正常启动关闭CDH5.16.1
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>
Java 实践:生产者与消费者
查看>>
[转]IOCP--Socket IO模型终结篇
查看>>
js 获取视频的第一帧
查看>>
各种正则验证
查看>>
观察者模式(Observer)
查看>>
python中numpy.r_和numpy.c_
查看>>
egret3D与2D混合开发,画布尺寸不一致的问题
查看>>
freebsd 实现 tab 命令 补全 命令 提示
查看>>
struts1和struts2的区别
查看>>
函数之匿名函数
查看>>
shell习题第16题:查用户
查看>>