RQNOJ 꽃집 쇼윈도 배치

2092 단어 OJ
클릭하여 링크 열기
사고방식: 동적 기획 분석: 1 제목은 가장 큰 미학적 값을 찾아야 하고 표지 번호가 큰 것은 표지 번호가 작은 오른쪽에 있어야 한다. 그러면 꽃 i가 i행의 j열에 있으면 i+1송이가 j+1 뒤의 2가 뚜렷한 단계에 나와야 한다는 것을 알 수 있다. 우리는 dp[i][j]로 첫 번째 꽃을 j열에 놓으면 얻을 수 있는 최대 미학적 값을 나타낸다. 그러면 dp[i][j]=max(dp[i-1][j])+num[j];여기에 꽃이 많을 때마다 놓을 수 있는 구간을 주의해야 한다. i번이 많으면 놓을 수 있는 구간이 i행이다. [i~V-F+n] 3문제는 꽃이 많지 않은 위치를 출력해야 한다. 그러면 상태가 이동할 때 위치를 기록하면 코드가 된다.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF = 1<<30;
const int MAXN = 110;

int n , m;
int num[MAXN][MAXN] , dp[MAXN][MAXN];
int path[MAXN][MAXN] , output[MAXN];

void solve(){
    for(int i = 1 ; i <= m-n+1 ; i++)
        dp[1][i] = num[1][i];
    memset(path , -1 , sizeof(path));
    for(int i = 2 ; i <= n ; i++){
        for(int j = i ; j <= m-n+i ; j++){
            dp[i][j] = num[i][j];
            int Max = -INF;
            int pos;
            for(int k = i-1 ; k < j ; k++){
               if(dp[i-1][k] > Max){
                   Max = max(Max , dp[i-1][k]); 
                   pos = k;
               }
            }
            dp[i][j] += Max;
            path[i][j] = pos;
        }
    }
    int ans = -INF;
    int pos , x , y;
    for(int i = n ; i <= m ; i++){
        if(ans < dp[n][i]){
            ans = max(ans , dp[n][i]);
            y = i; 
        }
    }
    printf("%d
" , ans); pos = n-1; x = n; output[pos--] = y; while(path[x][y] != -1){ output[pos--] = path[x][y]; y = path[x--][y]; } printf("%d" , output[0]); for(int i = 1 ; i < n ; i++) printf(" %d" , output[i]); printf("
"); } int main(){ while(scanf("%d%d" , &n , &m) != EOF){ for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= m ; j++) scanf("%d" , &num[i][j]); solve(); } return 0; }

좋은 웹페이지 즐겨찾기