链接:http://www.lintcode.com/zh-cn/problem/rogue-knight-sven/
在物质位面“现实”中,有n+1
个星球,分别为星球0,星球1,……,星球n。
每一个星球都有一个传送门,通过传送门可以直接到达目标星球而不经过其他的星球。
不过传送门有两个缺点。
第一,从星球i通过传送门只能到达编号比i
大,且与i
的差不超过limit
的星球。
第二,通过传送门到达星球j
,需要cost[j]
个金币。
现在,流浪剑客斯温到达星球0
后身上有m
个金币,请问他有多少种方法通过传送门到达星球n
?
注意事项
1 <= n <= 50
,0 <= m <= 100
,1 <= limit <= 50
,0 <= cost[i] <= 100
。- 由于cost[0]没有意义,题目保证cost[0] =
0
。
样例
给出 n = 1
, m = 1
, limit = 1
, cost = [0, 1]
,返回 1
。
解释:
方案1:星球0→星球1
给出 n = 1
, m = 1
, limit = 1
, cost = [0, 2]
,返回 0
。
解释:
无合法方案
给出 n = 2
, m = 3
, limit = 2
, cost = [0, 1, 1]
,返回 2
。
解释:
方案1:星球0→星球1→星球2
方案2:星球0→星球2
给出 n = 2
, m = 3
, limit = 2
, cost = [0, 3, 1]
,返回 1
。
解释:
方案1:星球0→星球2
class Solution {
public:
/**
* @param n: the max identifier of planet.
* @param m: gold coins that Sven has.
* @param limit: the max difference.
* @param cost: the number of gold coins that reaching the planet j through the portal costs.
* @return: return the number of ways he can reach the planet n through the portal.
*/
long long getNumberOfWays(int n, int m, int limit, vector<int> &cost) {
// Write your code here
//dp[i][j]表示到达星球i时剩余金币为j的方式数
vector<vector<long long>> dp(n + 1, vector<long long>(m + 1, 0));
//初始化,在星球0金币数为m
dp[0][m] = 1;
//对于星球i,i-1到i-limit可以直接到达
//dp[i][k]表示剩余金币为k的方式数,由于花销为cost[i],
//则在前一个到达的星球其对应的方式数为dp[pos][k+cost[i]](i-limit <= pos <= i-1)
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= limit&&j<=i; ++j)
{
for (int k = 0; k + cost[i] <= m; ++k)
{
dp[i][k] += dp[i - j][k + cost[i]];
}
}
}
//将剩余钱数的各种方式数相加得到结果
long long res = 0;
for (int i = 0; i <= m; ++i)
res += dp[n][i];
return res;
}
};