dp FAQ

20598 단어 동적 기획
  • poj1163 http://poj.org/problem?id=1163수탑 dp[i][j]=max(dp[i-1][j-1], dp[i-1][j])+a[i][j];
  • #include 
    #include 
    using namespace std;
    
    int a[105][105];
    int dp[105][105];
    
    int main()
    {
        int n;
        while(cin>>n)
        {
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=i;j++)
                {
                    cin>>a[i][j];
                    dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
                }
            }
            int ans=-1;
            for(int i=1;i<=n;i++)
            {
                if(anscout<return 0;
    }
    

    1차원 그룹만 저장할 수 있어 이번이 가장 좋고 공간을 절약할 수 있다
    #include 
    #include 
    using namespace std;
    
    int a[105][105];
    int dp[105];
    
    int main()
    {
        int n;
        while(cin>>n)
        {
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=i;j++)
                {
                    cin>>a[i][j];
                }
            }
            for(int i=1;i<=n;i++)
            dp[i]=a[n][i];
            for(int i=n-1;i>=0;i--)
            {
                for(int j=1;j<=i;j++)
                {
                    dp[j]=max(dp[j],dp[j+1])+a[i][j];
                }
            }
            cout<1]<return 0;
    }
    
  • 최장 연속 서열hdu1231dp[i]는 i로 끝나는 최장 연속 서열이고 dp[i]=max(dp[i-1]+a[i], a[i]).
  • #include 
    #include 
    #include 
    using namespace std;
    
    const int maxn=10005;
    
    int a[maxn];
    int dp[maxn];
    int pos[maxn];//pos[i], i        
    int n;
    
    int main()
    {
        while(cin>>n&&n)
        {
            memset(dp,0,sizeof(dp));
            memset(pos,0,sizeof(pos));
            for(int i=0;icin>>a[i];
            int ans=-1;
            for(int i=0;iif(dp[i-1]<=0)
                pos[i]=a[i];
                else
                pos[i]=pos[i-1];
                dp[i]=max(a[i],dp[i-1]+a[i]);
                ans=max(ans,dp[i]);
            }
            if(ans<0)
            {
                printf("0 %d %d
    "
    ,a[0],a[n-1]); continue; } for(int i=0;iif(dp[i]==ans) { printf("%d %d %d
    "
    ,dp[i],pos[i],a[i]); break; } } } return 0; }

    hdu1003 마찬가지로 아래 표시만 기록합니다
    #include 
    #include 
    #include 
    using namespace std;
    
    const int maxn=100005;
    
    int a[maxn];
    int dp[maxn];
    int pos[maxn];
    
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int cas=1;cas<=t;cas++)
        {
            memset(dp,0,sizeof(dp));
            memset(pos,0,sizeof(pos));
            int n;
            int ans=-100000000;
            scanf("%d",&n);
            for(int i=0;i"%d",&a[i]);
            for(int i=0;iif(dp[i-1]<0)
                pos[i]=i;
                else
                pos[i]=pos[i-1];
                dp[i]=max(dp[i-1]+a[i],a[i]);
                ans=max(ans,dp[i]);
            }
            for(int i=0;iif(ans==dp[i])
                {
                    printf("Case %d:
    "
    ,cas); printf("%d %d %d
    "
    ,ans,pos[i]+1,i+1); } } if(cas!=t) printf("
    "
    ); } return 0; }
  • 최장 증자 서열 원문:http://blog.csdn.net/qq_34681949/article/details/52186675하나.O(n*n) 알고리즘, dp[i]는ai를 끝으로 하는 최장 상승 서열의 길이를 표시하고,ai를 끝으로 하는 최장 상승 서열은 두 가지가 있다.
  • 1.   ai    ;  2.   j<i aj[i]=max{1,dp[j]+1|j 
    #include  
    #include  
    #include  
    using namespace std;  
    int a[10010];  
    int dp[10010];  
    int main()  
    {  
        int n;  
        while(scanf("%d",&n)!=EOF)  
        {  
            for(int i=0;iscanf("%d",&a[i]);  
                dp[i]=1;  
            }  
            int ans=0;  
            for(int i=1;ifor(int j=0;jif(a[j]1,dp[i]);  
    }  
    }  
    ans=max(ans,dp[i]);  
    }  
    printf("%d",ans);  
    }  
    return 0;  
    }

    둘.O(nlogn) 알고리즘, dp[i]= 길이가 i+1인 상승자 서열 중 끝부분 요소의 최소값(존재하지 않으면 INF)이라는 알고리즘에서 STL의lowerbound () 함수는 편리합니다.
    #include  
    #include  
    #include  
    using namespace std;  
    #define INF 0x3f3f3f  
    int dp[10010];//dp[i]     i+1           ;   
    int a[10010];  
    int main()  
    {  
        int n;  
        while(scanf("%d",&n)!=EOF)  
        {  
            for(int i=0;iscanf("%d",&a[i]);  
                dp[i]=INF;//    memset     INF,    0 -1;  
                          //   fill(dp,dp+n,INF);   
            }  
            for(int i=0;i//  >=a[i]      ,  a[i]  ;   
            }  
            printf("%d
    "
    ,lower_bound(dp,dp+n,INF)-dp);// INF ; } return 0; }

    hdu1257 최장 비증가 서열http://acm.hdu.edu.cn/submit.php?pid=1257
    dp[i]=max(dp[i],dp[j]+1) ( 0<=j
    #include 
    #include 
    
    using namespace std;
    
    const int maxn=1010;
    
    int a[maxn];
    int dp[maxn];
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=-1)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                dp[i]=1;
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=i;j++)
                {
                    if(a[i]>a[j])
                    dp[i]=max(dp[i],dp[j]+1);
                }
            }
            int ans=0;
            for(int i=1;i<=n;i++)
            ans=max(ans,dp[i]);
            printf("%d
    "
    ,ans); } return 0; }

    4. 최장 공통 하위 서열 dp[i, j] = 0 i=0 | | j=0 dp[i, j] = dp[i-1] [j-1] +1i>0, j>0, a[i] = b[j] dp[i, j] = max(dp[i-1] [j], dp[j] [j] [j-1]) i>0, j>0, a[i]!b[j]
    #include
    #include
    #include
    using namespace std;
    
    char a[1005],b[1005];
    int dp[1005][1005];
    
    int main()
    {
        while(cin>>a>>b)
        {
            int len1=strlen(a);
            int len2=strlen(b);
            memset(dp,0,sizeof(dp));
            for(int i=1; i<=len1; i++)
                for(int j=1; j<=len2; j++)
                {
                    if(a[i-1]==b[j-1])
                        dp[i][j]=dp[i-1][j-1]+1;
                    else
                        dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            cout<return 0;
    }
    
  • 최장 회신 하위 시퀀스 최장 회신 하위 시퀀스 LPS(Longest Palindromic Subsequence)는 동적 계획의 대표적인 제목입니다.분석한 후에 이 문제의 실질은 다음과 같다. 임의의 문자열에 대해 머리와 꼬리가 같으면 그의 최장 회문 서열은 반드시 머리와 꼬리를 제거한 후의 최장 회문 서열에 머리와 꼬리를 더해야 한다.만약 머리와 꼬리가 다르다면, 그것의 가장 긴 회문 서열은 머리를 뺀 부분의 가장 긴 회문 서열과 끝을 뺀 부분의 가장 긴 회문 서열의 비교적 긴 것이다.DP로 전환하는 상태 이동 방정식은 다음과 같다. 문자열을 s로 설정하고 dp[i][j]는 s[i....j]를 나타내는 LPS를 설정한다.상태 전이 방정식: i>j일 때 dp[i][j]=0;i = j일 때 dp[i][j]=1;i
    시간 복잡도 O(n*n)로 데이터 비교 시간에만 적합하며 비교적 크면 마차 끌기
    #include 
    #include 
    using namespace std;
    
    int dp[400][400];
    
    void LPS(char s[],int len)
    {
        for(int i=len-1;i>=0;i--)
        {
            dp[i][i]=1;
            for(int j=i+1;jif(s[i]==s[j])
                dp[i][j]=dp[i+1][j-1]+2;
                else
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
            }
        }
    }
    int main()
    {
        char s[305];
        while(cin>>s)
        {
            memset(dp,0,sizeof(dp));
            int len=strlen(s);
            LPS(s,len);
            cout<0][len-1]<return 0;
    }
    
  • 좋은 웹페이지 즐겨찾기