暑假訓練 Multiplication Puzzle POJ
阿新 • • 發佈:2018-12-13
**題目大意:**一個數組兩端資料不能取,每次取出資料所得分數為所取資料與相鄰兩個資料的乘積,求取出所有數字(不包括兩端)後的最小得分數。。。POJ - 1651
程式碼如下:
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int inf = 0x3f3f3f3f; int n, a[109], dp[109][109]; int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); /* for(int i = n-1; i > 1; i--) { dp[i][i] = a[i]*a[i-1]*a[i+1]; for(int j = i+1; j < n; j++) { dp[i][j]=inf; for(int l = i; l <= j; l++) dp[i][j] = min(dp[i][j], dp[i][l-1]+dp[l+1][j]+a[l]*a[i-1]*a[j+1]); } } */ for(int i = 2; i < n; i++) { dp[i][i] = a[i]*a[i-1]*a[i+1]; for(int j = i-1; j >= 2; j--) { dp[j][i] = inf; for(int l = j; l <= i; l++) dp[j][i] = min(dp[j][i], dp[j][l-1]+dp[l+1][i]+a[l]*a[j-1]*a[i+1]); } } printf("%d", dp[2][n-1]); return 0; }
dp[i][j]表示的是取出區間[i, j]的最小得分數。 找出轉換公式dp[j][i] = min(dp[j][i], dp[j][l-1]+dp[l+1][i]+a[i+1]*a[j-1]*a[l]即可。 要注意i,j的順序和方向,保證轉換公式中dp[j][l-1]和dp[l+1][i]已經求出。 儘管以前見識過區間dp了,但看到這個題並沒有和區間dp聯想到一起。。。