注意一點:
在加法的時候最大值肯定是兩個最大值相加,最小值肯定是兩個最小值相加
在乘法的時候 最大值可能是兩個最大值相乘 也可能是兩個最小值相乘,最小值可能是兩個最小值相乘,也可能是乙個最大值和乙個最小值
然後我用的是記憶化搜尋: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...