持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
一、题目描述:
Hercy 想要为购买第一辆车存钱。他 每天 都往力扣银行里存钱。
最开始,他在周一的时候存入 1 块钱。从周二到周日,他每天都比前一天多存入 1 块钱。在接下来每一个周一,他都会比 前一个周一 多存入 1 块钱。
给你 n ,请你返回在第 n 天结束的时候他在力扣银行总共存了多少块钱。
示例 1:
输入:n = 4
输出:10
解释:第 4 天后,总额为 1 + 2 + 3 + 4 = 10 。
示例 2:
输入:n = 10
输出:37
解释:第 10 天后,总额为 (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4) = 37 。注意到第二个星期一,Hercy 存入 2 块钱。
示例 3:
输入:n = 20
输出:96
解释:第 20 天后,总额为 (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4 + 5 + 6 + 7 + 8) + (3 + 4 + 5 + 6 + 7 + 8) = 96 。
提示:
- 1 <= n <= 1000
二、思路分析:
设f(k)为第k天的存款
则:f(k) = f(k-1) + step
无后置性:第k天的存款等于第k-1天的存款 + 当天的存款,和第k-2,k-3天的存款无关
最优子结构:第k天的存款等于step(k-1) + step(k-2) +... +step(1) 第k天的存款是经历每一天存下来的,且当天的存款都是固定且作为第二天存款的基数累加的
只是说这里贪心算法是动态规划思想的一个特例,每天新增的存款step都是一个状态,一般动态规划当前状态都是由一个以上的前一个状态取最理想的计算出来的。
三、AC 代码:
public class Solution {
public int totalMoney(int n) {
//总存款
int result = 0;
int week = 1;
for (int i = 1; i <= n; i++) {
int step = 0;
if (i % 7 == 1) {
//当前是第几周
week = week(i);
step = week;
}else {
//当日新增存款=step(周基数)+距离这周一过了几天
step = week + (i-1)%7;
}
result += step;
}
return result;
}
/**
* 第n天是第几周
* @param n
*/
public int week(int n) {
return n / 7 + 1;
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.totalMoney(20));
}
}