现在的位置: 首页 > 综合 > 正文

【HDU】4507 吉哥系列故事——恨7不成妻 数位DP

2017年10月15日 ⁄ 综合 ⁄ 共 1407字 ⁄ 字号 评论关闭

传送门:【HDU】4507 吉哥系列故事——恨7不成妻

题目分析:状态限制条件要多,保证不会重叠。dp用结构体表示,记录当前状态下符合条件的数的个数,数和,数平方和。然后由于数是可以递推的,于是这题可数位DP了。具体怎么推也不难,自己思考下吧~

数位DP还有好多题没写,论文也还没看,找个时间再看吧。。。

希望在上海赛之前还能有所提高~

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define clr( a , x ) memset ( a , x , sizeof a )

const int mod = 1e9 + 7 ;

struct Node {
	LL num , sum , sqr ;
	Node () {}
	Node ( LL num , LL sum , LL sqr ) : num ( num ) , sum ( sum ) , sqr ( sqr ) {}
} dp[20][2][7][7] ;

int vis[20][2][7][7] , Time ;
int digit[20] ;
LL pow[20] ;

Node dfs ( int cur , int limit , int t1 , int t2 , int t3 ) {
	if ( !cur ) return Node ( !t1 && t2 && t3 , 0 , 0 ) ;
	if ( vis[cur][t1][t2][t3] == Time && !limit ) return dp[cur][t1][t2][t3] ;
	vis[cur][t1][t2][t3] = Time ;
	Node ans = Node ( 0 , 0 , 0 ) ;
	int n = limit ? digit[cur] : 9 ;
	For ( i , 0 , n ) {
		int a = t1 || i == 7 , b = ( t2 * 10 + i ) % 7 , c = ( t3 + i ) % 7 ;
		LL tmp = i * pow[cur - 1] % mod ;
		Node pre = dfs ( cur - 1 , limit && i == digit[cur] , a , b , c ) ;
		LL num = ( ans.num + pre.num ) % mod ;
		LL sum = ( ans.sum + pre.sum + tmp * pre.num ) % mod ;
		LL sqr = ( ans.sqr + pre.num * tmp % mod * tmp + 2 * tmp * pre.sum + pre.sqr ) % mod ;
		ans = Node ( num , sum , sqr ) ;
	}
	if ( !limit ) dp[cur][t1][t2][t3] = ans ;
	return ans ;
}

LL cal ( LL n ) {
	int n1 = 0 ;
	LL tmp = n ;
	while ( tmp ) {
		digit[++ n1] = tmp % 10 ;
		tmp /= 10 ;
	}
	++ Time ;
	 ;
	return dfs ( n1 , 1 , 0 , 0 , 0 ).sqr ;
}

void solve () {
	LL L , R ;
	scanf ( "%I64d%I64d" , &L , &R ) ;
	printf ( "%I64d\n" , ( cal ( R ) - cal ( L - 1 ) + mod ) % mod ) ;
}

int main () {
	int T ;
	pow[0] = 1 ;
	rep ( i , 1 , 20 ) pow[i] = pow[i - 1] * 10 % mod ;
	clr ( vis , 0 ) ;
	Time = 0 ;
	scanf ( "%d" , &T ) ;
	while ( T -- ) solve () ;
	return 0 ;
}

抱歉!评论已关闭.