英文:
Count ways to reach end from start stone and come back, without taking using the same stone twice with at most K jumps at each step
问题
Richard是一只经常在加拿大和美国之间通勤的企鹅。
具体而言,加拿大位于位置1,美国位于位置N。在2到N的位置上,有冰块,Richard可以跳到这些冰块上。只有当abs(i-j)<=k时,Richard才能从位置i跳到位置j。
Richard不相信浪费时间,所以当他通勤时,他总是朝着一个方向移动。这意味着当从加拿大通往美国时,位置的数量是单调递增的,而当从美国通往加拿大时,位置的数量是单调递减的。
在秋季和春季,加拿大和美国之间的冰块会融化,这使得Richard的通勤变得复杂。如果Richard跳上一个冰块,那个冰块会融化到足够程度,无法在返回的旅程中使用。
计算Richard从加拿大到美国再返回的不同方式的数量。如果在某个方向上,Richard在一种方式中使用了一个冰块,但在另一种方式中没有使用该冰块,则这两种方式是不同的。
2<=k<=N<=5000
样例输入:
5 3
样例输出:
12
我应该如何解决这个问题?
n = 5000
k = 400
dp = [[0]*(n+1) for _ in range(n+1)]
dp[1][1] = 1
start_time = time.time()
for i in range(2, n+1):
total = 0
for j in range(i-k, i):
dp[j][i] = dp[j][j]
total += dp[j][i]
dp[i][i] = total
end_time = time.time()
print(dp[-1][-1] % 998244353)
这是我用于计算去程的代码,但回程怎么办?
英文:
Richard is a penguin who regularly commutes between Canada and the United States.
Specifically, Canada is at location 1
, and the United States is at location N.
In locations 2 through N, there are ice blocks that Richard can jump on. Richard can jump from location i to location j if and only if abs(i-j)<=k.
Richard does not believe in wasting time, so when he is commuting in one direction, he will always move in that direction. This means that when commuting from Canada to the United States, locations are monotonically increasing in number, and when commuting from the United States to Canada, locations are monotonically decreasing in number.
Richard's commute is complicated during the fall and spring when the ice is thawing between Canada and the United States. If Richard jumps on an ice block, that ice block will melt enough that it will not be usable on the return journey.
Count the number of distinct ways that Richard can do a round-trip commute from Canada to the United States and back. Two ways are distinct if, in some direction, Richard uses an ice block travelling in that direction in one way but not in the other way.
2<=k<=N<=5000
sample input:
5 3
sample output
12
how should i approach this problem?
n = 5000
k = 400
dp = [[0]*(n+1) for _ in range(n+1)]
dp[1][1] = 1
start_time = time.time()
for i in range(2, n+1):
total = 0
for j in range(i-k, i):
dp[j][i] = dp[j][j]
total += dp[j][i]
dp[i][i] = total
end_time = time.time()
print(dp[-1][-1] % 998244353)
here is my code for calculating the way there, but what about the way back?your text
答案1
得分: 4
想象一下给岩石2到N-1上色。如果它们在从加拿大到美国的路上使用,就将它们涂成红色;如果它们在返回的路上使用,就将它们涂成蓝色。如果它们根本没有被使用,就将它们涂成灰色。你的问题是,有多少种方式可以给岩石上色,使得不存在长度大于等于k的非红色或非蓝色的间隙。
创建一个矩阵DP[r][b],其中包含给岩石上色的方式数量,使得最高的红色岩石为r,最高的蓝色岩石为b,并且不存在非法的红色间隙小于r或蓝色间隙小于b。
如果按照r+b、max(r,b)等的递增顺序填充矩阵,那么每个元素可以从先前填充的元素中以O(k)的时间计算出来。然后,根据填充好的矩阵,可以在O(k^2)的时间内计算出最终答案。
由于矩阵的大小为(N-2)^2,所以这需要O(kN^2)的时间。
英文:
Imagine coloring rocks 2 through N-1. Color them red if they're used on the way from Canada to the US, and color them blue if they're used on the way back. Leave them gray if they are not used at all. Your question is how many ways you can color the rocks such that there are no gaps of >= k non-red stones or non-blue stones.
Make a matrix DP[r][b] that contains the number of ways to color the stones such that the highest red stone is r, the highest blue stone is b, and there are no illegal red gaps < r or blue gaps < b.
If you fill out the matrix in order of increasing r+b, max(r,b), etc., then each element can be calculated in O(k) time from previously filled out elements. Then your final answer can be computed in O(k<sup>2</sup>) time given the filled out matrix.
Since the matrix has size (N-2)<sup>2</sup>, this takes O(kN<sup>2</sup>) time.
答案2
得分: 0
这似乎对你在描述中提到的示例起作用。也许你可以添加更多的示例?
JavasScript代码:
function f(n, k) {
dp = {};
function g(i, lastS, lastN) {
if (i == n) {
return 1;
}
const key = String([i, lastS, lastN]);
if (key in dp) {
return dp[key];
}
let result = 0;
if (i - lastS < k && i - lastN < k) {
result += g(i + 1, lastS, lastN);
}
if (i - lastN < k) {
result += g(i + 1, i, lastN);
}
if (i - lastS < k) {
result += g(i + 1, lastS, i);
}
return dp[key] = result;
}
return g(2, 1, 1);
}
var inputs = [
[5, 3], // 12
[3, 2] // 3
];
for (const [n, k] of inputs) {
console.log(`(${ n }, ${ k }) -> ${ f(n, k) }`);
}
希望对你有帮助!
英文:
This seems to work for the example you have in the description. Maybe you could add more examples?
JavasScript code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function f(n, k) {
dp = {};
function g(i, lastS, lastN) {
if (i == n) {
return 1;
}
const key = String([i, lastS, lastN]);
if (key in dp) {
return dp[key];
}
let result = 0;
if (i - lastS < k && i - lastN < k) {
result += g(i + 1, lastS, lastN);
}
if (i - lastN < k) {
result += g(i + 1, i, lastN);
}
if (i - lastS < k) {
result += g(i + 1, lastS, i);
}
return dp[key] = result;
}
return g(2, 1, 1);
}
var inputs = [
[5, 3], // 12
[3, 2] // 3
];
for (const [n, k] of inputs) {
console.log(`(${ n }, ${ k }) -> ${ f(n, k) }`);
}
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论