Noip 2014 날아다니는 새

3156 단어
제목 전송문
나의 어린 황새는 불복을 표시했다
이 문제를 가방으로 바꿀 수 있다는 것도 신기한데..

컨디션

f[i][j]는 좌표\((i, j)\)에 대한 최소 클릭 횟수를 표시하고 도달할 수 없으면\(inf\)로 설정합니다.

옮기다


다음 코드 세션은 비교적 혼란스러울 수 있습니다.
  • 사전 프로세싱은 첫 번째 열 어디에서나 시작할 수 있으므로 첫 번째 열은\(0\)
    for(int i=1;i<=m;i++) dp[0][i]=0;
  • 상승은 전열에서 이 앞줄로 날아올랐을 수도 있고 (한 번 눌렀을 수도 있다) 현재 몇 번이나 눌렀을 수도 있다. 완전배낭
    for(int j=jum[i].x;j<=jum[i].x+m;j++)
        dp[i][j]=min(dp[i-1][j-jum[i].x],dp[i][j-jum[i].x])+1;
    상승으로 볼 수도 있고 특판이 정상으로 날아올랐을 수도 있다. 정상으로 날아오르면 더 이상 올라갈 수 없기 때문이다
    for(int j=m+1;j<=jum[i].x+m;j++)
        dp[i][m]=min(dp[i][m],dp[i][j]);
  • 하강하면 전열에서 떨어질 수 있다. 즉, 같은 열에서 한 번만 하강하면\(01\)배낭
    for(int j=1;j<=m-jum[i].y;j++)
        dp[i][j]=min(dp[i][j],dp[i-1][j+jum[i].y]);
  • 으로 볼 수 있다.
  • 파이프를 통과할 수 없습니다. 값은\(inf\)
    for(int j=1;jhigh[i];j--) dp[i][j]=inf;
  • 입니다.
    남은 주의해야 할 것은 출력입니다. 사실 주의해야 할 것도 없습니다. 할 수 있습니다\(DP\), 나머지는 모두 말하기 쉽습니다...(하지만 저는 DP를 할 줄 모릅니다!!!)

    \(\tt{code}\)

    #include
    #include
    #include
    #include
    #define inf 0x7ffffff
    #define gc getchar();
    using namespace std;
    int read(){int k=0;char c=gc;while(!isdigit(c))c=gc;while(isdigit(c)){k=k*10+c-48;c=gc;}return k;}
    int read_c(){int k=0;char c=gc;while(c'z')c=gc;return c-'a';}
    struct hhh{
        int x,y;
    }jum[10010];
    int high[10010],low[100010],flag[100010];
    int dp[10010][2010];
    int main(){
        int n=read(),m=read(),k=read();
        //=======    
        for(int i=1;i<=n;i++)
          jum[i].x=read(),jum[i].y=read();
        for(int i=1;i<=n;i++) low[i]=1, high[i]=m;
        for(int i=1;i<=k;i++){
            int p=read(),l=read(),h=read();
            flag[p]=1; low[p]=l+1; high[p]=h-1;;    
        }
        memset(dp,127,sizeof(dp));
        //======DP  
        for(int i=1;i<=m;i++) dp[0][i]=0;
        for(int i=1;i<=n;i++){
            for(int j=jum[i].x;j<=jum[i].x+m;j++)
              dp[i][j]=min(dp[i-1][j-jum[i].x],dp[i][j-jum[i].x])+1;
              
            for(int j=m+1;j<=jum[i].x+m;j++)
              dp[i][m]=min(dp[i][m],dp[i][j]);
              
            for(int j=1;j<=m-jum[i].y;j++)
              dp[i][j]=min(dp[i][j],dp[i-1][j+jum[i].y]);
              
            for(int j=1;jhigh[i];j--)
              dp[i][j]=inf;
        }
        //    
        int ans=inf;
        for(int i=low[n];i<=high[n];i++)
          if(dp[n][i]<=100000)
            ans=min(ans,dp[n][i]);
        if(ans!=inf)
          printf("1
    %d",ans); else{ ans=0; for(int i=1;i<=n;i++){ bool hhh=0; for(int j=1;j<=m;j++) if(dp[i][j]<=100000){ if(flag[i]) ans++; hhh=1; break; } if(!hhh) break; } printf("0
    %d",ans); } return 0; }

    전재 대상:https://www.cnblogs.com/wxl-Ezio/p/9911379.html

    좋은 웹페이지 즐겨찾기