您的位置:首页 > 大数据 > 人工智能

【codeforces】gym 101138 K. The World of Trains【前缀和优化dp】

2016-10-31 19:09 411 查看
题目链接:K. The World of Trains

记录一个横着的前缀dp和以及斜着的前缀dp,复杂度O(n2)

#include <bits/stdc++.h>
using namespace std ;

typedef pair < int , int > pii ;
typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 3500 ;
const int mod = 1e9 + 7 ;

int dp[MAXN][MAXN] , f[MAXN][MAXN] , g[MAXN][MAXN] ;
int n , d , t , k ;

int pm ( int x , int n ) {
LL res = 1 ;
while ( n ) {
if ( n & 1 ) res = res * x % mod ;
x = 1LL * x * x % mod ;
n >>= 1 ;
}
return res ;
}

void solve () {
if ( k == 1 ) {
if ( t + d - 1 == n ) printf ( "1\n" ) ;
else printf ( "0\n" ) ;
return ;
}
clr ( dp , 0 ) ;
clr ( f , 0 ) ;
clr ( g , 0 ) ;
dp[0][0] = 1LL * k * pm ( k - 1 , mod - 2 ) % mod ;
f[0][0] = 0 ;
for ( int i = 1 ; i <= n ; ++ i ) {
for ( int j = 0 ; j <= t ; ++ j ) {
f[i][j] = ( f[i - 1][j] + dp[i - 1][j] ) % mod ;
if ( i - d >= 0 ) f[i][j] = ( f[i][j] - dp[i - d][j] + mod ) % mod ;
dp[i][j] = ( dp[i][j] + 1LL * ( k - 1 ) * f[i][j] ) % mod ;
if ( i - d >= 0 && j ) {
g[i][j] = ( g[i - 1][j - 1] + dp[i - d][j - 1] ) % mod ;
}
dp[i][j] = ( dp[i][j] + 1LL * ( k - 1 ) * g[i][j] ) % mod ;
}
}
printf ( "%d\n" , dp
[t] ) ;
}

int main () {
while ( ~scanf ( "%d%d%d%d" , &n , &d , &t , &k ) ) solve () ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces