Codeforces-1140D Minimum Triangulation(假DP贪心+真水题)

题目: 传送门
思路: 将一个多边形划分成多个三角形,一定有个顶点,所有三角形会经过这个点,我们不妨把这个点成为聚点,用dp[i]表示聚点为i时三角形的权值和,当n为5时,i 为1是,dp[1] = 1* 2* 3+1* 3* 4+1* 4* 5.
dp[2] = 2* 3* 4+2* 4* 5+2* 5* 1.可以得出dp[2] = (dp[1] - 1*2 3) / 1 2+215.
则 dp[i] = (dp[i-1] - (i-1) *i *(i+1)) / (i-1) * i +i *(i-1) *(i-2);
代码:

long long dp[550];
int main() {
    int n;
    cin>>n;
    long long ans = 0;
    for(int i = 2;i<n;i++) {
        dp[1]+=i*(i+1);
    }
    //cout<<dp[1]<<endl;
    ans = dp[1];
    for(int i =2;i<=n;i++) {
        dp[i] = (dp[i-1]-(i-1)*(i-(i-1)/n*n)*(i+1-i/n*n))/(i-1)*i;
        //cout<<dp[i]<<'?'<<endl;
        dp[i] += i*(i-1+n-(i-2+n)/n*n)*(i-2+n-(i-3+n)/n*n);
        //cout<<dp[i]<<endl;
        ans = min(ans,dp[i]);
    }
    cout<<dp[1]<<endl;
    return 0;
}

测了几组样例,会发现聚点为1时一定最小,直接输出dp[1]即可,当然也可以用ans记录所有dp[]的最小值再输出.

猜你喜欢

转载自blog.csdn.net/qq_43305984/article/details/88865636