考点
思路
由题,面值的范围是1 ~ n,而和的范围也是1 ~ n
以和为4为例,要拼成4,只有1 、 2、 3这三个面额组成,或者只有一个4
所以我们只需要判定:
- 如果
1、2、3组成4的情况等于numWays[4](编程时为3),说明4不存在
- 如果
1、2、3组成4的情况再加1等于numWays[4](编程时为3),说明4存在
- 其余情况都非法,因为不可能大于
numWays[4],直接返回
暴力的二维:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public: vector<int> findCoins(vector<int>& numWays) { vector<int> ans; int n = numWays.size(); int f[105][105]; memset(f, 0, sizeof(f)); f[0][0] = 1; for (int i = 1; i <= n; ++i) { if (numWays[i - 1] == f[i - 1][i] + 1) { ans.push_back(i); for (int j = 0; j <= n; ++j) { f[i][j] += f[i - 1][j]; if (j >= i) f[i][j] += f[i][j - i]; } } else if (numWays[i - 1] == f[i - 1][i]) { for (int j = 0; j <= n; ++j) f[i][j] += f[i - 1][j]; } else { return vector<int>(); } } return ans; } };
|
压缩后的一维:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: vector<int> findCoins(vector<int>& numWays) { vector<int> ans; int n = numWays.size(), f[105]; memset(f, 0, sizeof(f)); f[0] = 1; for (int i = 1; i <= n; ++i) { if (numWays[i - 1] == f[i] + 1) { ans.push_back(i); for (int j = i; j <= n; ++j) f[j] += f[j - i]; } else if (numWays[i - 1] == f[i]) { } else { return vector<int>(); } } return ans; } };
|