荣誉版主
- 积分
- -2403
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2010-5-4
- 最后登录
- 1970-1-1
|
//Two Solution:
//one is direct search, exponential time complexity, sort like NPC
//Another is dynamic programming, typical pseudo DP for NPC problem, equation:
//F(x,y) = f(x, y-1) + f(x-v(y), y-1) + f(x-2v(y), y-1) + ... + f(x-s*v(y), y-1), ((s+1)*v(y) > x)
//x is the amount of money, v(y) is the value of the change coin, y is the index
int WaysOfChange1(int nMoney, int a[], int n)
{
assert(nMoney >= 0 && n >= 0);
assert(a);
if (0 == nMoney) return 1;
if (0 == n) return 0;
int nRet = 0;
int nCur = 0;
while (nCur*a[0] <= nMoney)
{
nRet += WaysOfChange1(nMoney-nCur*a[0], a+1, n-1);
nCur++;
}
return nRet;
}
int WaysOfChange2(int nMoney, int a[], int n)
{
assert(nMoney > 0 && a && n > 0);
sort(a, a+n);
int** pDP = new int* [nMoney];
for (int i = 0; i < nMoney; i++)
pDP[i] = new int[n];
//init
for (int i = 0; i < nMoney; i++)
pDP[i][0] = ((i+1)%a[0]) == 0 ? 1 : 0;
for (int i = 0; i < n; i++)
pDP[0][i] = (1%a[i]) == 0 ? 1 : 0;
//F(x,y) = f(x, y-1) + f(x-v(y), y-1) + f(x-2v(y), y-1) + ... + f(x-s*v(y), y-1), ((s+1)*v(y) > x)
for (int i = 1; i < nMoney; i++)
for (int j = 1; j < n; j++)
{
int nVal = 0;
int nCur = 0;
while (nCur*a[j] <= i+1)
{
if (nCur*a[j] == i+1)
nVal += 1;
else
nVal += pDP[i-nCur*a[j]][j-1];
nCur++;
}
pDP[i][j] = nVal;
}
int nRet = pDP[nMoney-1][n-1];
for (int i = 0; i < nMoney; i++)
delete []pDP[i];
delete []pDP;
return nRet;
} |
|