C - Pangu and Stones 区间DP

题面链接:https://cn.vjudge.net/contest/319950#problem/C

题意:将N个石头合并每一次可以合并[L,R]的石头,并且消费这些被合并石头的价格总和。问把N个石头合并的最小消费。无法合并输出0

难度:2017北京站的一个铜-银题,整体思路很容易出,转移有点小复杂,感觉难度对标CF2300

思路:dp[i][j][k] 代表 [i,j]区间内合并到剩有k个石头的最小消费

i可以从后移到前,j从i+1开始移到N。对于一个区间利用一个[i,j]间的一个位置p转移 即  dp[i][j][k] 等于 [i,p]区间合并得剩1个石头的最小消费加上[p+1,j]合并到剩k-1个的最小消费。因为到这一步这两个区间的值肯定更新过 所以对于所有的P肯定能找到一个最小值。这是转移k>=2的情况。

同理对于k=1枚举p的位置  再枚举 右边区间的数量 [l-1,r-1] 。左边加右边的最小消费然后再加上整个区间的和。找到一个最小值。

答案最后就是 dp[1][n][1]

总复杂度 O(n^4) N的大小100所以轻松过

#include 

using namespace std;
typedef pair P;
typedef long long ll;

ll dp[105][105][105];
int a[105];
int pref[105];

int main()
{
    int n,l,r;
    while(cin>>n>>l>>r){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            pref[i] = pref[i-1] + a[i];
        }

        for(int i=0;i<=n;i++){
            for(int j=i;j<=n;j++)
                for(int k=0;k<=n;k++) dp[i][j][k] = 1<<30;
        }

        for(int i=1;i<=n;i++)dp[i][i][1] = dp[i][i][0] = 0;
        for(int i=n;i;i--){
            for(int j=i+1;j<=n;j++){
                for(int p=i;p

 

你可能感兴趣的:(acm)