nyoj737 돌멩이 합병【구간dp】

1648 단어 dp병합
논문과 다른 아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아아
논문 문제 마지막에 수조를 구하고 [1,n][2,n+1]을 찾아야 하는데......[n, n+n+1]의 최고치, 이 문제는 첫 번째 문제만 출력하면 됩니다.
이 문제는 특별히 나를 괴롭히는 점이 하나 있다. 구간마다 두 단락으로 나뉘는데, 뒷부분의 값이 아직 두루 퍼지지 않았는데, 어떡하지?그래서 1층 순환은 구간의 길이이고 2층 순환은 구간의 시작이며 3층 순환은 구간의 중점이다.보아하니 dp의 관건도 상태 이동 방정식을 쓰는 것만은 아닌 것 같다.
/******************
nyoj737
2016.2.18
732 	868 	C/C++	02-18 15:47:11
******************/
#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
int f[403][403],n,num[403],t[403];
void init()
{
    t[0]=0;
    for(int i=1;i<=2*n-1;i++)t[i]=t[i-1]+num[i];
}
void cal()
{
    memset(f,0x3f3f3f3f,sizeof(f));
    for(int i=1;i<=2*n-1;i++) f[i][i]=0;
    for(int k=1;k<n;k++)//length
        for(int i=1;i<=n;i++)//start
            for(int j=i;j<i+k;j++)//mid
            {
                f[i][i+k]=min(f[i][i+k],f[i][j]+f[j+1][i+k]+t[i+k]-t[i-1]);
            }
    //for(int i=1;i<=n;i++)for(int j=i+1;j<=i+n-1;j++) printf("i=%d,j=%d,f=%4d\t\t",i,j,f[i][j]);
}
int main()
{
    //freopen("cin.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        for(int i=n+1;i<=2*n;i++) num[i]=num[i-n];
      //  for(int i=1;i<=2*n-1;i++) printf("i=%d,num=%d
",i,num[i]); init(); cal(); int maxn=0x3f3f3f3f; // for(int i=1;i<=n;i++) printf("i=%d,j=%d,f=%d
",i,i+n-1,f[i][i+n-1]); printf("%d
",f[1][n]); } return 0; }

좋은 웹페이지 즐겨찾기