DP 시작 문제 - 타워 문제 (poj1163)

2151 단어 동적 기획
DP 문제를 10개 풀고 나서 이 수탑 문제를 풀면 분명히 손에 익는다. 빨리 쓸 뿐만 아니라 AC도 한 번에 두 가지 방법을 썼다.이것으로 보아 깊이 파고드는 것은 이치에 맞지 않는 것이 아니다, 하하~~
수탑 문제의 상태 이동 방정식은 쉽게 얻을 수 있다. 나는 위에서 아래로 생각하는 것이다(즉 점차적인 사상). 여기서 흔히 볼 수 있는 두 가지 DP의 작법을 말한다. 하나는 점차적인 방식으로 하는 것이다. 그의 요구는 매번 구하는 이 상태이다. 계산은 앞에서 이미 계산한 상태에서 얻어진 것이고 비교적 실현하기 쉽지만 한 문제마다 쉽게 생각해 낼 수 있고 다른 하나는 기억화 검색 방식이다.즉, 내가 결과를 계산하면 나중에 사용할 수 있도록 저장한다. (예를 들어 어떤 초기화 수조가 마이너스이고, 산출 결과는 저장되며, 수조가 정설명이라는 것을 발견하면 바로 사용한다.)
여기서 나는 모두 점차적으로 추진하는 방식을 사용했다. 단지 두 번째 방식은 공교롭다. 왜냐하면 나는 1~n에서 dp[i-1][j-1]의 j-1은 0까지 갈 수 있기 때문이다. 그러나 dp[i-1][0]는 dp[i-1]이 없을 것이다[1][큰 (dp[i-1][0]는 0,memset으로 초기화했다)
#include 
#include 
int max(int a,int b)
{
    return a>b?a:b;
}
 int main()
 {
     int i,j,n,ans;
     int a[105][105];
     int dp[105][105];
     memset(a,0,sizeof(a));
     scanf("%d",&n);
     for (i=1;i<=n;i++)
     for (j=1;j<=i;j++)
     {
        scanf("%d",&a[i][j]);
     }
     dp[1][1]=a[1][1];
     for (i=2;i<=n;i++)
     for (j=1;j<=n;j++)
     {
         if (j==1)//                              
            dp[i][j]=dp[i-1][j]+a[i][j];
        else
          if (j==i)//                             
            dp[i][j]=dp[i-1][j-1]+a[i][j];
        else
            dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
     }
     ans=-99999;
     for (i=1;i<=n;i++)
     ans=max(ans,dp[n][i]);//             
     printf("%d
",ans); return 0; }

변종 문제: LightOJ 1004
#include 
#include 
int max(int a,int b)
{
    return a>b?a:b;
}
 int main()
 {
     int i,j,n,ans;
     int a[105][105];
     int dp[105][105];
     memset(a,0,sizeof(a));
     memset(dp,0,sizeof(dp));
     scanf("%d",&n);
     for (i=1;i<=n;i++)
     for (j=1;j<=i;j++)
     scanf("%d",&a[i][j]);
     for (i=1;i<=n;i++)
     for (j=1;j<=n;j++)
     dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
     ans=-9999;
     for(i=1;i<=n;i++)
     ans=max(ans,dp[n][i]);
     printf("%d
",ans); return 0; }

좋은 웹페이지 즐겨찾기