本文最后更新于:2023年12月15日 晚上
前言
帮群友随手写写的
题目描述
数据范围
1 0 4 > y > x > 1 10^4>y>x>1 1 0 4 > y > x > 1
解题思路
动态规划
对于这类问题,我们可以使用递归解决,设d f s ( i , j ) dfs(i,j) df s ( i , j ) ,其中i = x i=x i = x ,j = y j=y j = y
根据题意得
当x > 1 x>1 x > 1 ,d f s ( i , j ) = y + d f s ( i − 1 , j − 1 ) dfs(i,j)=y+dfs(i-1,j-1) df s ( i , j ) = y + df s ( i − 1 , j − 1 )
当x = 1 x=1 x = 1 ,d f s ( i , j ) = y dfs(i,j)=y df s ( i , j ) = y
这样我们就可以写一个递归了 这里我为了方便 所以用python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def dfs (i,j ): if i == 1 : return j else : return j+dfs(i-1 ,j-1 ) x = 2 y = 3 print (dfs(x,y)) x = 1 y = 4 print (dfs(x,y))
这里是不用记忆化搜索的,因为递归的过程中并没有重复计算
现在我们来1:1
翻译成递推
1 2 dp[i][j] = j+dp[i-1][j-1] dp[i][j] = j
我们可以看到,如果直接从0开始遍历 会出现负数下标 因此我们可以+1
则变成
1 2 dp[i+1][j+1] = j+dp[i][j] dp[i+1][j+1] = j
由于题目已给1 0 4 > x > y > 1 10^4>x>y>1 1 0 4 > x > y > 1 ,所以递归和二维dp是过不了本题的
得考虑状压dp,可以把他压缩成一维dp
这里的状态转移主要是j 因此可以缩写成
d p [ i + 1 ] = i dp[i+1] = i
d p [ i + 1 ] = i
dp代码
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dp = [0 for _ in range (10002 )]def dfs (x,y ): for i in range (1 ,y+1 ): dp[i+1 ] = i return sum (dp[y+2 -x:y+2 ]) x = 2 y = 3 print (dfs(x,y)) x = 1 y = 4 print (dfs(x,y))
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int dp[10002 ];int dfs (int x,int y) { for (int i = 1 ; i <= y;i++){ dp[i+1 ] = i; } int ans = 0 ; for (int i = y+2 -x; i<=y+2 ;i++){ ans+=dp[i]; } return ans }int main () { int x = 2 ; int y = 3 ; cout<<dfs (x,y)<<endl; x = 1 ; y = 4 ; cout<<dfs (x,y); return 0 ; }
数学
这里就要开始分析了,假设x = 2 , y = 3 x=2,y=3 x = 2 , y = 3
从代码执行的角度来看无非是,3 + d f s ( 2 − 1 , 3 − 1 ) 3+dfs(2-1,3-1) 3 + df s ( 2 − 1 , 3 − 1 ) ,实际发生的计算为3 + 2 3+2 3 + 2
同样的道理,当x = 1 , y = 4 x=1,y=4 x = 1 , y = 4 时,实际发生计算为4 4 4
总结出一个规律,首先是
( y − 1 ) + ( y − 1 − 1 ) + ( y − 1 − 1 ) + . . . (y-1)+(y-1-1)+(y-1-1)+...
( y − 1 ) + ( y − 1 − 1 ) + ( y − 1 − 1 ) + ...
终止条件为x = 1 x=1 x = 1
但是这样做,好想有点难思考
我们可以先吧0 + 1 + 2 + 3.... + y 0+1+2+3....+y 0 + 1 + 2 + 3.... + y 算出来,再减去0 + 1 + 2 + 3... + x 0+1+2+3...+x 0 + 1 + 2 + 3... + x
这里的计算,可以套用我博客的之前的公式,详情请看->点我
a n s = { i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) k / 2 = 0 i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) + ( k / / 2 ) k / 2 ! = 0 ans=\begin{cases} i*k+(k-1)*(k//2) & k/2=0 \\ i*k+(k-1)*(k//2)+(k//2) & k/2!=0\end{cases}
an s = { i ∗ k + ( k − 1 ) ∗ ( k //2 ) i ∗ k + ( k − 1 ) ∗ ( k //2 ) + ( k //2 ) k /2 = 0 k /2 ! = 0
把这里的k k k ,换成x x x 和y y y 就行了,同时i = 1 i=1 i = 1 ,a n s = ( y − x , y ) ans=(y-x,y) an s = ( y − x , y )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def ans (x,y ): o = 0 ;p = 0 ; if x % 2 == 0 : o = 1 *x+(x-1 )*(x//2 ) else : o = 1 *x+(x-1 )*(x//2 )+(x//2 ) if y % 2 == 0 : p = 1 *y+(y-1 )*(y//2 ) else : p = 1 *y+(y-1 )*(y//2 )+(y//2 ) return p-o x = 2 y = 3 print (ans(y-x,y)) x = 1 y = 4 print (ans(y-x,y))
数学代码
Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def ans (x,y ): o = 0 ;p = 0 ; if x % 2 == 0 : o = 1 *x+(x-1 )*(x//2 ) else : o = 1 *x+(x-1 )*(x//2 )+(x//2 ) if y % 2 == 0 : p = 1 *y+(y-1 )*(y//2 ) else : p = 1 *y+(y-1 )*(y//2 )+(y//2 ) return p-o x = 2 y = 3 print (ans(y-x,y)) x = 1 y = 4 print (ans(y-x,y))
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int ans (int x,int y) { int o = 0 ; int p = 0 ; if (o%2 ==0 ){o = 1 *x+(x-1 )*(x/2 );} else {o = o = 1 *x+(x-1 )*(x/2 )+(x/2 );} if (y%2 ==0 ){p = 1 *y+(y-1 )*(y/2 );}else {p=1 *y+(y-1 )*(y/2 )+(y/2 );} return p-o; }int main () { int x = 999 ; int y = 1000 ; cout<<ans (y-x,y)<<endl; x = 1 ; y = 4 ; cout<<ans (y-x,y); return 0 ; }
后记
喜欢的话,多多支持,同时也关注一下我