Below problem was in a contest (it's over now) contest link.
Its seems variant of classic coin denomination problem -
Given an array(k elements) having coin values and a number n. We need to answer the number of ways we can make the denomination of n. we can solve it by DP
which will take O(n*k)
time. Now in contest problem instead of giving coin value array, there is a value m, and coin values are all possible powers of m ex. n= 200, m=3.
so we have coin values with [3^0, 3^1, 3^2, 3^3, 3^4]
, higher powers are not useful for the example].
I used DP
approach here but its giving TLE
. By seeing the time limit testcases<=10000
, n<=10000
, m<=10000
, I assume we have to solve it for given n,m
in O(n)
time[may need to optimize this one also. Please help me to solve this problem.
My solution using 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;
}