硬币的变化(硬币的价值是m的幂)
Coin change (coin values are powers of m)
下面的问题是一个比赛(现在已经结束了)比赛环节。
这似乎是经典硬币面额问题的变体-给定一个数组(k个元素),它有硬币值和一个数字n。我们需要回答n的命名方法的个数。我们可以用DP
来解决它,这将花费O(n*k)
的时间。现在在竞赛问题中,不是给出硬币值数组,而是有一个值m,硬币值是m的所有可能的幂,例如n= 200, m=3.
,所以我们有[3^0, 3^1, 3^2, 3^3, 3^4]
的硬币值,更高的幂对于这个例子来说是没有用的。
我在这里使用DP
方法,但它给出TLE
。通过testcases<=10000
, n<=10000
, m<=10000
的时间限制,我认为我们必须在O(n)
的时间内解决n,m
的问题[可能还需要优化这个问题]。请帮我解决这个问题。我的解决方案是使用DP
.
#include <bits/stdc++.h>
#include <stdio.h>
using namespace std;
int solve(vector<int>&vec, int n){
cout<<"n= "<<n<<": m= "<<vec.size()<<endl;
int r=n+1, c=vec.size()+1;
vector<int>row(c,0);
vector<vector<int> >dp(r, row);
for(int i=0;i<c;i++)
dp[0][i]=1;
for(int i=1;i<r;i++){
for(int j=1;j<c;j++){
int a=0;
if(i-vec[j-1]>=0)
a=dp[i-vec[j-1]][j];
dp[i][j]=a+dp[i][j-1];
}
}
return dp[n][c-1];
}
int main()
{
ios::sync_with_stdio(false);
int tc,n,m;
cin>>tc;
while(tc--){
cin>>n>>m;
vector<int>temp;
int index=0;
temp.push_back(1);
while(temp[index]*m<=n){
temp.push_back(temp[index]*m);
index++;
}
int result=solve(temp,n);
cout<<result<<endl;
}
return 0;
}
"硬币变化"和类似的分区问题通常从记忆中受益匪浅。我发现,基于m的幂次硬币值的聪明的数学技巧,无法击败带有记忆的直接递归算法。(在回答一个相关问题时,我更详细地说明了记忆对分区算法的影响)
下面的Javascript代码示例解决了n,m = 200,3
在0.026ms中的示例,以及最坏的情况,n,m = 10000,2
在我的i5桌面上在2.8ms;我不知道比赛的时间限制是多少,但是10000个随机案例大约需要3秒。c++实现当然会快得多。
function coinPowers(n, m) {
if (n < 1 || m < 1) return 0;
if (n < m || m == 1) return 1;
var power = Math.floor(Math.log(n) / Math.log(m));
var memo = [];
for (var i = 0; i < n; i++) memo[i] = [];
return partition(n, m, power);
function partition(n, m, power) {
var count = memo[n - 1][power];
if (count) return count;
var coin = Math.pow(m, power), count = 1;
for (var p = power; p > 0; coin /= m, p--) {
if (coin < n) count += partition(n - coin, m, p)
else if (coin == n) ++count;
}
return (memo[n - 1][power] = count);
}
}
document.write(coinPowers(200, 3) + "<BR>");
document.write(coinPowers(200, 2) + "<BR>");
document.write(coinPowers(10000, 2) + "<BR>");
相关文章:
- 在计算中使用二的幂有多有利可图
- 如何在硬币兑换问题中找到硬币的数量
- 有效地将大数存储为 2 的幂用于路径问题
- 计算 O(1) 中的幂函数
- 查找数字是否为 2 的幂的时间复杂度
- C++在不使用pow或循环的情况下计算一个数字的幂
- 使用用户定义的函数查找数字的幂时出现问题
- C++ 返回具有最小硬币的数组/向量以获得价值动态规划
- 仅在 2 的幂上错过了 clang 中的优化
- 10的幂的表查找
- 虽然这个简单的 C++ 程序可以打印 2 的幂,但它有很多问题时可以工作
- 一个整数的log2,该整数是2的幂
- 更好的算法来检查一个数字是否既不是素数也不是单个素数的幂
- 我怎样才能从 n 得到一个提高到自身等于 n 的幂的数字?
- 长整数不适用于 8 的幂C++
- 我在IEEE754乘法中失去了 2 的幂
- C++编译器识别2的幂吗
- 快速映射,其中键是 2 的幂 (C++)
- 为什么发出如此复杂的代码来将有符号整数除以 2 的幂
- 硬币的变化(硬币的价值是m的幂)