[문제풀이] 낙곡 2704 포병 진지(NOI 2001)
6500 단어 문제풀이
그러면 먼저 dp방정식은 빨리 추측할 수 있다. dp[L][S][i]는 현재 상태가 S이고 이전 줄의 상태가 L임을 나타낸다. 현재 i줄을 고려했다.
dp[L][S][i]=max(dp[L][S][i],dp[FL][L][i-1]+Sum[S]); 여기서 FL은 상단의 상태를 나타내고 Sum[S]는 현재 상태 S에 1이 포함되어 있음을 나타냅니다.
그러면 이 dp방정식이 생기면 즐겁게 전달할 수 있지만 이 문제는 몇 가지 세부 사항이 있으니 주의해야 한다.
1. 위치마다 언덕인지 아닌지 판단
이것은 아주 잘 해결된다. 한 줄의 입력을 모두 2진수(평원은 0이고 언덕은 1)로 바꾸고 판단을 기다리는 상태와 직접 비트 연산을 하면 된다. 바로 S&a[i]이다. 비트 연산 결과가 0이 아니라면 어떤 위치가 언덕 위에 놓여 있다는 것이다. 즉, 현재 상태가 비합법적이라는 것이다.
2. 각 상태에 포병 두 명이 있는지 좌우 거리가 두 칸 이내인지 판단
이것은 머리를 써서 생각해 보면 우리는 신기한 결론을 발견할 수 있다. 만약에 현재 상태를 나타내는 2진수 비트 연산을 왼쪽으로 한 번 옮기면 이 결과와 원래 상태로 비트 연산과 조작을 한 번 한다. 만약에 결과가 0이 아니라면 반드시 두 포병의 왼쪽 오른쪽 거리가 한 칸 안에 존재할 것이다.같은 이치로 왼쪽으로 두 자리를 옮기면 좌우 거리가 두 칸 안에 있다는 것을 판단할 수 있다.이 과정은 바로 S&(S<<1), S&(S<2)이다.
3. 각 열마다 포병이 있는지 없는지 판단
이것은 바로 현재 상태로 이전의 두 줄과 나누면 된다. 바로 S&L, S&FL이다. 만약에 조작 결과와 0이 되지 않는다면 몇몇 열의 앞줄에 포병이 있다는 것을 의미한다. 즉, 현재 상태가 합법적이지 않다는 것이다.
마지막으로 말하자면, 반드시 스크롤 그룹을 사용해야 한다. (한 줄과 두 줄만 사용하기 때문에 세 줄만 스크롤해야 한다.) 그렇지 않으면 MLE 0이 될 것이다. (나는 애초에 이렇게 비참했다.)
자, 세부 사항은 모두 말했습니다. 다음은 구체적인 코드가 실현되었습니다.
#include
using namespace std;
int n,m,ans,dp[(1<<10)][(1<<10)][3]/* */,a[105],Sum[(1<<10)];
char x;
int getsum(int S) // S 1
{
int tot=0;
while(S) {if(S&1) tot++; S>>=1;}
return tot;
}
int main()
{
cin>>n>>m;
for(int i=0;ifor(int j=0;jcin>>x,a[i]<<=1,a[i]+=(x=='H'?1:0); //
for(int i=0;i1<// Sum
for(int S=0;S1<if(!(S&a[0] || (S&(S<<1)) || (S&(S<<2))))
dp[0][S][0]=Sum[S]; //
for(int L=0;L1<for(int S=0;S1<if(!(L&S || L&a[0] || S&a[1] || (L&(L<<1)) || (L&(L<<2)) || (S&(S<<1)) || (S&(S<<2)))) //
dp[L][S][1]=Sum[S]+Sum[L];
for(int i=2;ifor(int L=0;L1<if(L&a[i-1] || (L&(L<<1)) || (L&(L<<2))) continue; //
for(int S=0;S1<if(S&a[i] || L&S || (S&(S<<1)) || (S&(S<<2))) continue; //
for(int FL=0;FL1<if(FL&L || FL&S || FL&a[i-2] || (FL&(FL<<1)) || (FL&(FL<<2))) continue; //
dp[L][S][i%3]=max(dp[L][S][i%3],dp[FL][L][(i-1)%3]+Sum[S]); //
}
}
}
for(int L=0;L1<for(int S=0;S1<1)%3]); //
cout<return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
49일차 - 2022.04.20Baekjoon에서 문제풀이 1) 문제 : 첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제/ 첫째 줄에 N(1 ≤ N ≤ 100)이 주어진다. 첫째 줄부터 N번째 줄까지 차례대로 별...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.