凸多邊形的劃分
阿新 • • 發佈:2019-01-24
題目描述
給定一具有N個頂點(從1到N編號)的凸多邊形,每個頂點的權均已知。問如何把這個凸多邊形劃分成N-2個互不相交的三角形,使得這些三角形頂點的權的乘積之和最小?
輸入輸出格式
輸入格式:第一行 頂點數N(N<50)。 第二行 N個頂點(從1到N)的權值,權值為小於32768的整數。
一行,為各三角形頂點的權的乘積之和最小值。
輸入輸出樣例
輸入樣例#1:5 121 122 123 245 231輸出樣例#1:
12214884
思路:
設dp(i,j)表示i到j這一段連續的n邊形劃分成兩部分後最小乘積
暴力列舉i到j之間頂點k
轉移方程:dp[i][j]=min(dp[i][j],(dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]))
具體思路可以參考別的部落格
說幾個我犯的智障錯誤
a陣列開成int後面資料型別轉換出了點小問題;忘記三角形三個頂點不能重合;dp陣列忘記初始化然後魔怔般瘋狂輸出0
這種。
以下程式碼
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define ll long long using namespace std; int n; ll a[100]; ll dp[100][100]; int main() { memset(dp,0x3f,sizeof(dp)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=n;i>=1;i--) { for(int j=i+1;j<=n;j++) { if(j-i==1)//容不下一個三角形(參見上述錯誤。) dp[i][j]=0; else if(j-i==2) dp[i][j]=a[i]*a[i+1]*a[i+2];//因為此時i和j中間只剩一個頂點了所以直接計算即可 else for(int k=i+1;k<=j-1;k++) { dp[i][j]=min(dp[i][j],(dp[i][k]+dp[k][j]+a[i]*a[j]*a[k])); } } } printf("%lld",dp[1][n]); return 0; }