DP(1)-선형 DP

8153 단어
욕심은 예로밖에 없다. DP는 일반적으로 규칙을 본다. Dynamic Programming, teach you how to program your life.DP, 전칭 동적 기획(dynamic programming)은 운기획학의 한 가지로 다단계 결정 과정에 가장 최적화된 수학 방법을 구하는 것이다.다단계 의사결정 과정은 이런 특수한 활동 과정을 가리킨다. 문제는 시간 순서에 따라 약간의 상호 연계된 단계로 분해할 수 있고 모든 단계에서 의사결정을 해야 한다. 모든 과정의 의사결정은 의사결정 서열이다.DP의 가장 뚜렷한 특징은 최적화되고 후효성이 없다는 것이다. 이것은 우리가 문제를 해결하는 데 좋은 기초를 제공했다.최장 상승 서열은 n개의 수를 주고 최장 상승 서열의 길이를 구한다.여기서 우리는 f수 그룹을 설정할 수 있다. fi는 전 i위의 최장 상승 서열의 길이를 나타낸다.i위에 대해 우리는 이 분이 앞의 i-1위보다 큰지 판단해야 한다. 앞의 것보다 크면 조건을 만족시키는 i-1위에서 f의 값이 가장 큰 누적 1을 선택하면 구할 수 있다.
#include
using namespace std;
int n,a[10010],f[10010];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
     cin>>a[i];
    f[1]=1;
    for(int i=2;i<=n;i++)
     for(int j=1;jif(a[i]>a[j])
         f[i]=max(f[i],f[j]+1); 
     }
    cout<return 0;
}

가장 긴 공통 문자열은 문자열 a와 b를 정하고 a와 b의 가장 긴 공통 문자열의 길이를 구합니다.이것도 매우 뚜렷한 선형 DP이다. 우리는 여전히 f로 가장 좋은 결과를 저장한다. i위에 대해 우리는 문자열 a의 i위와 문자열 b의 j위가 같은지 판단해야 한다. 만약에 같으면 지난번의 기초 위에서 +1, 다르면 fi-1, j 및 fi, j-1에서 최대치를 제거하고 누적되지 않습니다.
#include
using namespace std;
string a,b;
int f[110][110];
int main()
{
    cin>>a>>b;
    if(a[0]==b[0])
     f[0][0]=1;
    else
     f[0][0]=0;
    for(int i=0;i<=a.size()-1;i++)
     for(int j=0;j<=b.size()-1;j++)
     {
        if(a[i]==b[j])
         f[i][j]=f[i-1][j-1]+1;
        else
         f[i][j]=max(f[i-1][j],f[i][j-1]);
     }
     cout<1][b.size()-1]<return 0;
}

또한 여러 문자열에 대해 우리는 가차원을 선택하고, 몇 개 있으면 가차원을 넣는다.합창대형 N명의 학생은 일렬로 서고, 음악 선생님은 K명의 학생을 골라 합창대형으로 서야 한다.합창대형은 이런 대형을 가리킨다. K명의 학우를 왼쪽에서 오른쪽으로 순서대로 1,2,,,...,K로 설정하면 그들의 키는 각각 T1,T2,...,TK로 설정하면 그들의 키는 T1Ti+1>····>TK(1≤i≤K)를 만족시킨다.이 문제는 최장 상승자 서열과 매우 비슷하다. 다른 것은 최고점에 도달하면 하락으로 변한다. 그러면 반대로 보면 뒤에서 앞으로 가장 긴 상승자 서열로 볼 수 있다.정반을 두 번 하고 최고점을 얻으면 보류된 인원수를 구하고 상감하면 답을 얻을 수 있다.
#include
using namespace std;
int n,a[10001],f[10001],g[10001],ans;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
     cin>>a[i];
    for(int i=1;i<=n;i++)//          
     {
      f[i]=1;
     for(int j=1;j<=i;j++)
      if(a[i]>a[j])
       f[i]=max(f[i],f[j]+1);
      }
    for(int i=n;i>=1;i--)//          
     {
      g[i]=1;
     for(int j=n;j>=i;j--)
      if(a[i]>a[j])
       g[i]=max(g[i],g[j]+1);
     }
    for(int i=1;i<=n;i++)//     
     ans=max(f[i]+g[i]-1,ans);
    cout<return 0;
}

기선 문제는 한 강 양안에 n 대 도시가 있는데 두 강 사이에 항로가 하나 있기를 희망하지만 교차할 수 없다. 몇 개의 항로를 개통할 수 있느냐고 물었다.우선, 우리는 왼쪽 기슭의 도시에 대해 순서를 정한 다음에 오른쪽 기슭에 대해 최장 상승자 서열을 구한다. 가장 긴 최장 상승자 서열은 바로 개통된 항로이다.(왜냐고 묻지 마, 잘 모르겠어)
#include
using namespace std;
struct road
{
    int r,l;
}a[5110]={};
bool cmp(road c,road d)
{
    return c.lint main()
{
    int x,y,n,maxx=0;
    cin>>x>>y>>n;
    int f[5110]={};
    for(int i=1;i<=n;i++)
     cin>>a[i].l>>a[i].r;
    sort(a+1,a+n+1,cmp);
    f[1]=1;
    for(int i=2;i<=n;i++)
    {
     for(int j=1;jif(a[i].r>a[j].r&&f[j]>f[i]) f[i]=f[j];
     f[i]++;
    }
    for(int i=1;i<=n;i++)
    if(f[i]>maxx)
    maxx=f[i];
    cout<return 0;
} 

선형 DP는 위에서 말한 바와 같이 가방 문제는 다시 이야기하자...

좋은 웹페이지 즐겨찾기