HDU 1024 Max Sum Plus Plus(최대 하위 순서 와)

1562 단어 dpACM
제목 링크:http://acm.hdu.edu.cn/showproblem.php?pid=1024
제목:n 길이 의 서열 을 제시 하고 m 대 자 서열 을 찾 아 m 대 자 서열 과 최대
사고:dp[i][j]앞 에 있 는 j 개 수 는 i 대 서브 시퀀스 의 최대 합 으로 나 뉘 고 s[j]는 마지막 서브 시퀀스 의 끝 이 며,dp[i][j]=max(dp[i][j-1]+s[j],dp[i-1]+s[j]),그 중에서 i-1<=k<=j-1.상태 이동 은 s[j]가 하위 서열 에 가입 하거나 혼자서 하나의 서열(즉 dp[i-1][k]+s[j])이 되 거나 s[j-1]과 새로운 서열(즉 dp[i-1][k]+s[j])로 조합 하 는 것 으로 이해 할 수 있다.
       공간 과 시간의 제한 으로 인해 일정한 최적화 가 필요 하 다.스크롤 배열 의 방식 으로 공간 을 최적화 시 킬 수 있 고 시간 최적화 는 배열 을 통 해 기록 할 수 있다.
dp[i-1][k]의 최대 값 이면 됩 니 다.pre[j-1]배열 의 업 데 이 트 는 dp[i][j]를 계산 해 야 합 니 다.dp[i][j]는 업데이트 되 지 않 은 pre[j-1](업데이트 후 dp[i-1][k]와 유사 한 최대 값 을 사용 해 야 하기 때 문 입 니 다.  ->  dp[i][k]의 최대 값),pre[n]으로 최대 값 을 계속 저장 하면 됩 니 다.
      
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define inf 0x3f3f3f3f
#define maxn 1000030
using namespace std;

int s[maxn],pre[maxn],dp[maxn];

int main()
{
    int n,m;
    while (scanf("%d%d",&m,&n)!=EOF)
    {

        memset(pre,0,sizeof(pre));
        memset(dp,0,sizeof(dp));
        for (int i=1;i<=n;i++)
          scanf("%d",&s[i]);

        dp[0]=0;
        pre[0]=0;
        for (int i=1;i<=m;i++)
        {
            int tmp=-inf;
            for (int j=i;j<=n;j++)
            {

                dp[j]=max(dp[j-1]+s[j],pre[j-1]+s[j]);
                pre[j-1]=tmp;
                tmp=max(tmp,dp[j]);
            }
            pre[n]=tmp;
        }
        printf("%d
",pre[n]); } }

좋은 웹페이지 즐겨찾기