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

【HDU】5000 Clone 记忆化搜索

2017年11月20日 ⁄ 综合 ⁄ 共 977字 ⁄ 字号 评论关闭

传送门:【HDU】5000 Clone

题目分析:首先所有方案中各位的和都等于一个数x,然后这个x取到T[ i ]之和的二分之一时答案最大。

运气很好,蒙出来的。。。最后时刻AC。。。

有重复计算,所以可以用到记忆化搜索。

代码如下:

#include <cmath>
#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 REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )

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

int T[MAXN << 1] ;
int dp[MAXN << 1][MAXN] ;
bool vis[MAXN << 1][MAXN] ;
int n ;

void dfs ( int cur , int sum ) {
	vis[cur][sum] = 1 ;
	if ( cur == n ) {
		if ( T[n] < sum ) dp[cur][sum] = 0 ;
		else dp[cur][sum] = 1 ;
		return ;
	}
	dp[cur][sum] = 0 ;
	int tmp = min ( sum , T[cur] ) ;
	FOR ( i , 0 , tmp ) {
		if ( !vis[cur + 1][sum - i] ) dfs ( cur + 1 , sum - i ) ;
		dp[cur][sum] += dp[cur + 1][sum - i] ;
		if ( dp[cur][sum] >= mod ) dp[cur][sum] -= mod ;
	}
}

void solve () {
	int sum = 0 ;
	scanf ( "%d" , &n ) ;
	FOR ( i , 1 , n ) {
		scanf ( "%d" , &T[i] ) ;
		sum += T[i] ;
	}
	sort ( T + 1 , T + n + 1 ) ;
	sum >>= 1 ;
	FOR ( i , 0 , sum ) CLR ( vis[i] , 0 ) ;
	dfs ( 1 , sum ) ;
	printf ( "%d\n" , dp[1][sum] ) ;
}

int main () {
	int T ;
	scanf ( "%d" , &T ) ;
	while ( T -- ) solve () ;
	return 0 ;
}

抱歉!评论已关闭.