DFS(cur) 表示从cur开始最少能分多少组
然后next是 使cur到next最大
然后
if( next - cur >= 3 ){
ans = min( ans, 1 + DFS( next ) );
}
if( next - cur >= 4 ){
ans = min( ans, 1 + DFS( next - 1 ) );
}
if( next - cur >= 5 ){
ans = min( ans, 1 + DFS( next - 2 ) );
}
这三个判断是说 可以 分一个给后面 或者分两个给后面 或者一个都不给后面 来组成新的小组
然后就A啦~~~~
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
int dp[100010];
int K, N;
int pos[100010];
int DFS( int cur ){
if( cur >= N ){
return 0;
}
if( dp[cur] != -1 ){
return dp[cur];
}
int next = upper_bound( pos, pos + N, pos[cur] + K ) - pos;
int ans = MAX;
if( next - cur >= 3 ){
ans = min( ans, 1 + DFS( next ) );
}
if( next - cur >= 4 ){
ans = min( ans, 1 + DFS( next - 1 ) );
}
if( next - cur >= 5 ){
ans = min( ans, 1 + DFS( next - 2 ) );
}
return dp[cur] = ans;
}
int main(){
int T, Case = 1;
cin >> T;
while( T-- ){
cin >> N >> K;
K = 2 * K;
for( int i = 0; i < N; i++ ){
scanf( "%d", &pos[i] );
}
sort( pos, pos + N );
memset( dp, -1, sizeof( dp ) );
int ans = DFS( 0 );
if( ans < MAX ){
cout << "Case " << Case++ << ": " << ans << endl;
}else{
cout << "Case " << Case++ << ": " << -1 << endl;
}
}
return 0;
}