Running Routes 區間dp

題目鏈接 https://open.kattis.com/problems/runningroutes

題意

給你一個正 nn 邊多邊形,告訴你所有點和點之間是否可以連線,現在要你選出最多的連線,使得所有線之前兩兩不相交,問最多能選出多少條線。

做法

其實能感覺出來是區間 dpdp ,因爲如果一個 88 邊形,3和6連上後,7~2 和 4~5兩個區間都是一個新的狀態,但是emmm,原來自己是不寫這種題的。。

dp[i][j]dp[i][j] 的狀態是由 dp[i+1][j1]dp[i+1][j-1] 的狀態和 a[i][j]a[i][j] 的狀態決定的,即dp[i][j]=dp[i+1][j1]+a[i][j]dp[i][j]=dp[i+1][j-1]+a[i][j] ,最後所有的狀態都保存在 dp[i][i1]dp[i][i-1] 中。

代碼

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=505;
int n,a[maxn][maxn];
int dp[maxn][maxn];
int G(int x){
    if(x>n) return x-n;
    if(x<1) return x+n;
    return x;

}
int main(){
    scanf("%d",&n);
    rep(i,1,n){
        rep(j,1,n){
            dp[i][j]=0;
            scanf("%d",&a[i][j]);
        }
    }
    rep(i,1,n){
        dp[i][G(i+1)]=a[i][G(i+1)];
    }
    for(int len=2;len<=n-1;len++){
        for(int i=1,j=G(len+1);i<=n;i++,j=G(j+1)){
            dp[i][j]=dp[G(i+1)][G(j-1)]+a[i][j];
            for(int s=i;s!=j;s=G(s+1)){
                dp[i][j]=max(dp[i][j],dp[i][s]+dp[G(s+1)][j]);
            }

        }
    }
    /*printf("\n");
    rep(i,1,n){
        rep(j,1,n){
            printf("%d ",dp[i][j]);
        }
        printf("\n");
    }
    printf("\n");*/
    int ans=0;
    rep(i,1,n){
        ans=max(ans,dp[i][G(i-1)]);
    }
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章