poj 1179 記憶化搜尋

2021-06-20 11:28:10 字數 1593 閱讀 8008

注意一點:

在加法的時候最大值肯定是兩個最大值相加,最小值肯定是兩個最小值相加

在乘法的時候 最大值可能是兩個最大值相乘 也可能是兩個最小值相乘,最小值可能是兩個最小值相乘,也可能是乙個最大值和乙個最小值

然後我用的是記憶化搜尋:dp_min[i][j]表示區間i到j的最小值, dp_max[i][j]表示區間i到j的最大值

ac**如下:

#include #include #include #include #include using namespace std;

#define max 0x3f3f3f3f

char edge[55];

int num[55], n;

int ans[55];

int dp_min[55][55], dp_max[55][55];

char temp_edge[55];

int temp_num[55];

int max_ans;

int dfs_max( int start, int ends );

int calc( int a, int b )else

}int dfs_min( int start, int ends )

if( start == ends )

if( dp_min[start][ends] != max )

int ans = max;

for( int i = start; i < ends; i++ )else

ans = min( ans, temp );

} return dp_min[start][ends] = ans;

}int dfs_max( int start, int ends )

if( start == ends )

if( dp_max[start][ends] != max )

int ans = -max;

for( int i = start; i < ends; i++ )else

ans = max( ans, temp );

} return dp_max[start][ends] = ans;

}int main()

scanf( "%c %d", &edge[n], &num[n] );

//對每個邊進行遍歷

max_ans = -max;

for( int i = 1; i <= n; i++ )

memset( dp_max, 0x3f, sizeof( dp_max ) );

memset( dp_min, 0x3f, sizeof( dp_min ) );

ans[i] = dfs_max( 1, n );

max_ans = max( max_ans, ans[i] );

} cout << max_ans << endl;

int flag = 1;

for( int i = 1; i <= n; i++ )

cout << i;

flag = 0;

}} cout << endl;

} return 0;

}

poj 1179 矩陣鏈乘加括號

題意 多邊形遊戲,有n個頂點的多邊形,3 n 50 多邊形有n條邊,每個頂點中有乙個數字 可正可負 每條邊上或者是 號,或者是 號。邊從1到n編號,首先選擇一條邊移去,然後進行如下操作 1 選擇一條邊e和邊e連線著的兩個頂點v1,v2 2 用乙個新的頂點代替邊e和v1 v2,新頂點的值為v1 v2中...

POJ 1179 列舉 區間 DP

題意 傳送門 poj 1179 題解列舉初始時刪的邊,將環拆成鏈。觀察刪邊 縮點的過程,有明顯的區間性質,考慮用區間 dpdp dp求解。由於點權值可能出現負數,那麼在狀態轉移求最大值的過程中,要考慮負負得正的情況。d p i j 2 dp i j 2 dp i j 2 代表區間 i,j i,j i...

poj 1579(記憶化搜尋)

consider a three parameter recursive function w a,b,c if a 0 or b 0 or c 0,then w a,b,c returns 1 if a 20 or b 20 or c 20,then w a,b,c returns w 20,20...