兩題都是 dp[n]。
原題:
https://cses.fi/problemset/task/1633
題意:
給 n(1 ≤ n ≤ 10^6)。用 1~6 的骰子和成 n,有多少種方式?對 1e9+7 取模。
解題思路:
#include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007;
int main(){
    int n;
    cin>>n;
    vector<int> dp(n+1,0);
    dp[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=6;j++){
            if(i-j>=0){
                dp[i]=(dp[i]+dp[i-j])%MOD;
            }
        }
    }
    cout<<dp[n]<<"\n";
    return 0;
}
原題:
https://cses.fi/problemset/task/1637
題意:
給 n(1 ≤ n ≤ 10^6)。每一步可把 n 減去它十進位表示中的一個非零數字。問把 n 變成 0 的最少步數。
解題思路:
#include <bits/stdc++.h>
using namespace std;
void digits(int x, vector<int>& buf) {
    buf.clear();
    while (x > 0) {
        int d = x%10;
        if (d != 0) buf.push_back(d);
        x /= 10;
    }
}
int main() {
    int n; 
    cin >> n;
    const int INF = 1e9;
    vector<int> dp(n+1, INF);
    dp[0] = 0;
    vector<int> buf;
    for (int i=1; i<=n; i++) {
        digits(i, buf);
        int best = INF;
        for (int t=0; t<buf.size(); t++) {
            int d = buf[t];
            if (i-d >= 0) {
                int cand = dp[i-d] + 1;
                if (cand<best) best=cand;
            }
        }
        dp[i] = best;
    }
    cout << dp[n] << "\n";
    return 0;
}
原題:
https://leetcode.com/problems/climbing-stairs/description/
題意:
每步可走 1 或 2 階,爬到第 n 階有幾種走法?
解題思路:
f[n] = f[n-1] + f[n-2],f[0]=1,f[1]=1。
class Solution {
public:
    int climbStairs(int n) {
        long long a = 1, b = 1; // f[0], f[1]
        for (int i = 2; i <= n; i++) {
            long long c = a+b; // f[i]
            a = b; 
            b = c;
        }
        return b;
    }
};
原題:
https://leetcode.com/problems/house-robber/description/
題意:
nums[i] 為每棟房子的金額;不能搶相鄰兩棟。求最大收益。
解題思路:
class Solution {
public:
    int rob(vector<int>& nums) {
        long long prev2 = 0;  // dp[0]
        long long prev1 = nums.empty() ? 0 : nums[0]; // dp[1]
        for (int i = 2; i <= nums.size(); i++) {
            long long take = prev2 + nums[i-1];
            long long skip = prev1;
            long long cur = (take > skip) ? take : skip;
            prev2 = prev1;
            prev1 = cur;
        }
        return prev1;
    }
};