HDU 4620 Fruit Ninja Extreme 搜索

时间:2022-05-14 15:03:37

搜索+最优性剪枝。

DFS的下一层起点应为当前选择的 i 的下一个,即DFS(i + 1)而不是DFS( cur + 1 ),cur+1代表当前起点的下一个。没想清楚,TLE到死……

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> using namespace std; const int MAXN = ; struct node
{
int t, id;
int cnt;
int fruit[];
}; int N, M, W;
int ansN, tmpN;
node D[MAXN];
int tmp[MAXN];
int ans[MAXN];
bool vis[]; bool cmp( node a, node b )
{
return a.t < b.t;
} void chuli( int cnt )
{
for ( int i = ; i < cnt; ++i )
ans[i] = tmp[i];
return;
} int change( int i, int *temp )
{
int cnt = ;
for ( int j = ; j < D[i].cnt; ++j )
{
int idx = D[i].fruit[j];
if ( !vis[ idx ] )
temp[cnt] = idx, ++cnt;
}
return cnt;
} void MyRestore( int *temp, int cnt )
{ for ( int j = ; j < cnt; ++j )
{
vis[ temp[j] ] = false;
}
return;
} void DFS( int cur, int pre, int sum )
{
if ( tmpN > ansN )
{
ansN = tmpN;
chuli( tmpN );
}
if ( cur >= N ) return;
if ( tmpN + N - cur <= ansN ) return;
if ( M - sum < ) return; for ( int i = cur; i < N; ++i )
{
if ( pre != - && D[i].t - D[pre].t > W ) break; if ( D[i].cnt < ) continue;
int temp[];
int left = change( i, temp );
if ( left < ) continue; for ( int j = ; j < left; ++j )
{
int idx = temp[j];
vis[idx] = true;
} tmp[ tmpN++ ] = D[i].id;
DFS( i + , i, sum + left ); //i+1 不是 cur+1 !!!!!
--tmpN;
MyRestore( temp, left );
} return;
} int main()
{
//freopen( "1010.in", "r", stdin );
//freopen( "s.out", "w", stdout );
int T;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d%d%d", &N, &M, &W );
for ( int i = ; i < N; ++i )
{
D[i].id = i + ;
scanf("%d%d", &D[i].cnt, &D[i].t );
for ( int j = ; j < D[i].cnt; ++j )
scanf( "%d", &D[i].fruit[j] );
}
sort( D, D + N, cmp ); ansN = ;
tmpN = ;
memset( vis, false, sizeof(vis) );
DFS( , -, ); sort( ans, ans + ansN );
printf( "%d\n", ansN );
for ( int i = ; i < ansN; ++i )
{
if ( i ) putchar(' ');
printf( "%d", ans[i] );
}
puts("");
}
return ;
}