D 게임 HDU - 5693 (제 DP)

B와 D : 우리 모두는, 곰의 정도는이 좋아하는 캐릭터를 아시다시피

D 게임 : 오늘, 그것은 게임을 발명했다.

영어 곰 정도는, 그래서 여기에없는 매우 훌륭 D, 더 깊은 의미하지만입니다 등차 수열의 대신 (산술 시퀀스 백과 사전) D.의 허용 오차

이 게임은 우선 설정된 공차 곰 {D}도를 갖고, 후 순차적으로 정렬 된 N 디지털 쓰기되도록한다. 규칙은 간단합니다 :

  1. 선택 X (X≥2) 현재의 연속 숫자 배열을 정렬 나머지;

  2. X 1 체크 자릿수 연산 시퀀스를 구성 선택되고, 공차 d∈ {D};

  3. 두 충족하는 경우, 당신은 배열의 X 번호를 삭제할 수 있습니다;

  4. 당신이 더 많은 숫자를 삭제할 수 없습니다 때까지 1-3 단계를 반복합니다.

그 다음, 영리 충분한 경우 자리의 수 곰 최대의 정도가 삭제?
입력
첫번째 라인 정수 T (1≤T≤100) T.을 나타내는 데이터의 집합

두 정수 N에서 데이터의 각 세트는, M이 시작된다. 다음 라인은 N의 정수를 포함하고 순서화 된 어레이 아이 늘어서. 다음 라인 M은 정수이고, 디디 뮴 공차, 즉 주어진 세트 인

1≤N, M≤300

000≤Ai -1 000 000 000 000 000 Di≤1
출력
까지 삭제 디지털의 출력에 각 시험.
입력 샘플
. (3)
. (3) (1)
. (1) (2) (3)
. (1)
. (2) (3)
. (1) (2) 4
. 1 2
. 4 2
. 1. 3. 4. 3
. 1 2
샘플 출력
. 3
(2)
. (4)

아이디어 :
간격 DP
상태 F [I] [J]의 정의는 얼마나 많은 부분의 개수를 나타내는 경우는 전송 명확하지 않다, 제거 될 수있다.
J의 간격 내가 대신 프로그램, F [I] [J]의 가능성의 정의가 모두 삭제 할 수 있다면, 쉽게 처리 할 수있을 것이다.

하나의 명백한 결론은 다음과 같습니다 번호를 삭제하기 위해서는 삭제하고 세 가지를 삭제하는 두 가지로 분할 할 수 있습니다.

1의 간격 길이는 확실하게 삭제할 수 없습니다합니다. 도 2 및 3은 시간 간격의 길이는 별도 언급.
이어서 구간 [I, J]에서. 경우 토론의 두 가지 종류가 있습니다.
1.I j는 제거되었다 : 다음 F. 이때 [I] [J] F. = [I] [K] F.는 [. K + 1] [J]가로
본 : 2.I 및 j는 삭제되지 2 삭제로 나누었을 때 숫자 3과 번호를 삭제합니다. 두 개의 별도의 번호를 삭제하는 단계 [J]를 판정한다 - A [I ] 와 F [I + 1] [J - 1]. 삭제 수가 3 인 F [I + 1] [K - 1] F [K + 1] [J - 1] 토론이 [I]은 [K] 이 [J]

각 구간의 논의는 삭제하고 전면 F [i]는 i가 나타내는 참조의 최대 수를 정의 삭제 될 수있는 수는 될 수있다.
F는 [I]가 최대 = ([. 1 - I], F [J -. 1] + F를 I -. 1 + J)
N- 2 F 어레이로부터 계산 될 수있다.

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>

using namespace std;

typedef long long ll;
map<int,int>mp;
int can[305][305];
int f[305],a[305];

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        mp.clear();
        memset(can,0,sizeof(can));memset(f,0,sizeof(f));
        int n,m;scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)scanf("%d",&a[i]);
        for(int i = 1,x;i <= m;i++)scanf("%d",&x),mp[x] = 1;
        
        for(int len = 2;len <= n;len++)
        {
            for(int i = 1;i + len - 1 <= n;i++)
            {
                int j = i + len - 1;
                if(len == 2)
                {
                    if(mp[a[j] - a[i]])can[i][j] = 1;
                    continue;
                }
                else if(len == 3)
                {
                    int k = j - 1;
                    if(a[j] - a[k] == a[k] - a[i] && mp[a[j] - a[k]])can[i][j] = 1;
                    continue;
                }
                
                for(int k = i + 1;k < j - 1;k++)
                {
                    if(can[i][k] && can[k + 1][j])can[i][j] = 1;
                }
                
                if(can[i + 1][j - 1] && mp[a[j] - a[i]])can[i][j] = 1;
                for(int k = i + 3;k < j - 2;k++)
                {
                    if(can[i + 1][k - 1] && can[k + 1][j - 1])
                    {
                        if(a[j] - a[k] == a[k] - a[i] && mp[a[j] - a[k]])
                        {
                            can[i][j] = 1;
                        }
                    }
                }
            }
        }
        
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j < i;j++)
            {
                f[i] = max(f[i],f[i - 1]);
                if(can[j][i])f[i] = max(f[i],f[j - 1] + i - j + 1);
            }
        }
        printf("%d\n",f[n]);
    }
    return 0;
}

게시 된 676 개 원래 기사 · 원 찬양 18 ·은 30000 +를 볼

추천

출처blog.csdn.net/tomjobs/article/details/104213275