uva 111 - History Grading

點擊打開鏈接


題目意思:   給定一個正確的編號序列,然後對輸入的每一組序列找最長公共子序列


解題思路:     動態規劃

                       1:題目給定的n個數並不是表示當前位置的值就是Ai,而是表示第i個數放在第Ai個位置,看樣列4 2 3 1,說明1放在第四位,2放在第二位,3放在第三位,4放在第一位。
                       2:題目就是要求出最長的公共子序列,由於題目的n最大才20,那麼我們可以直接去枚舉。假設現在枚舉到Ai這個數,那麼我們就求i之前的所以數能夠和Ai構成連續的序列最大值dp[i],然後判斷能否更新最大值(max_point < dp[i]),最後輸出這個最大值即可。


代碼:


#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;
#define MAXN 25

int n;
int correct[25];//存儲正確的順序
int order[MAXN];//要求的順序
int dp[MAXN];

void solve(){
    int max_point = 0;
    int pos_i , pos_j;//記錄在correct數組中的位置
    dp[0] = 1;
    for(int i = 1 ; i < n ; i++){
        dp[i] = 1;//初始化爲1
        for(int j = i-1 ; j >= 0 ;j--){//搜索i之前的數
            for(int k = 0 ; k < n ; k++){//去correct數組中找到order[i] 和order[j]的位置
                if(correct[k] == order[i]) pos_i = k;
                if(correct[k] == order[j]) pos_j = k;
            }
            if(pos_i > pos_j){//如果i在j後面說明是連續的,求dp[i]
                if(dp[j]+1 > dp[i]) dp[i] = dp[j]+1;
            }
        }
        if(max_point < dp[i]) max_point = dp[i];//更新max_point
    }
    printf("%d\n" , max_point);
}

int main(){
    //freopen("input.txt" , "r" , stdin);
    int m;
    scanf("%d" , &n);
    for(int i = 1 ; i <= n ; i++){
        scanf("%d" , &m) ;  correct[m-1] = i;//求出correct數組
    }
    while(scanf("%d" , &m) != EOF){
        order[m-1] = 1;
        for(int j = 2 ; j <= n ; j++) {
            scanf("%d" , &m) ; order[m-1] = j;//求出order數組
        }
        solve();
    }
    return 0;
}



更多詳細信息請查看java教程網 http://www.itchm.com/forum-59-1.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章