100개의 동적 계획 – 34 UVA 10559 Blocks 상태의 정의 상태 전환 방정식
구간DP 같은 느낌이라니.응.그렇긴 한데, 단지 DP에 추가 조건을 붙여야 할 뿐이다
정의 상태 dp[i][j][k]는 구간 i~j를 표시하고 오른쪽에 j와 같은 색의 네모난 블록의 최대 값을 추가합니다
매번 가장 오른쪽을 없애는 것을 고려한다. 가장 오른쪽을 없애는 것을 고려한다면 두 가지 없애는 방법이 있다. 첫 번째는 바로 이번에 없애는 것이고, 두 번째는 남겨두고 나중에 없애는 것이다.
두 번째 없애는 방법은 i~j에서 j를 제외한 각 단락과 j가 같은 색의 블록의 오른쪽을 매거하는 것이다. 현재의 가장 오른쪽의 블록을 이 단락의 가장 오른쪽에 붙이는 것을 고려하면 언어 감각이 좀 명확하지 않다.
상태 이동 방정식은 dp[i][j][k]=dp[i][ri][0]+(j-ri+k)*(j-ri+k)이다. 그 중에서ri는 오른쪽 끝을 제거한 후의 새로운 시작점, 즉 오른쪽 첫 번째 j와 같은 색 블록이 없는 위치이다.
두 번째 이동은 각 단락이 j와 같은 색의 오른쪽을 매거하는 것이다. l로 가정하면 방정식은 dp[i][j]=max(dp[i][j][k], dfs(dp[i][le][k+j-ri])+dfs(dp[le+1][ri][0]))가 두 단락의 합에 해당한다.
좋은 제목이네요.
#include
#include
#include
using namespace std;
const int maxm=210;
int times,n,kcase,color[maxm],dp[maxm][maxm][maxm],dfs(int i=1,int j=n,int k=0);
void init();
int main(){
ios_base::sync_with_stdio(false);
cin>>times;
while(times--){
cin>>n;
init();
for(int i=1;i<=n;++i)
cin>>color[i];
cout<j)
return 0;
if(dp[i][j][k])
return dp[i][j][k];
int ri=j;
while(ri>=i&&color[j]==color[ri])--ri;
dp[i][j][k]=dfs(i,ri,0)+(j-ri+k)*(j-ri+k);
for(int le=i;le<=ri;++le)
if(color[le+1]!=color[le]&&color[le]==color[j])
dp[i][j][k]=max(dfs(i,le,j-ri+k)+dfs(le+1,ri,0),dp[i][j][k]);
return dp[i][j][k];
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ZOJ 3537 Cake(볼륨 판정 + 구간 DP)Here’s a polygon-shaped cake on the table. You’d like to cut the cake into several triangle-shaped parts for the invited...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.