Pangu and Stones HihoCoder - 1636

题意:给出n堆石头,每次最少合并其中l堆,最多合并r堆,问合成1堆最少需要花费多少时间

dp[i][j][k]表示i~j这个区间合成k堆所需要的最小时间,故可得状态转移方程式:
d为枚举的区间间隔
1.k==1 dp[i][i+d][1]=min(dp[i][i+d][1],dp[i][j][k]+dp[j+1][i+d][1]+sum[i][i+d])
(l-1<=k<=r-1)
2.k>=2 dp[i][i+d][k]=min(dp[i][i+d][k],dp[i][j][k-1]+dp[j+1][i+d][1])
此处k不用做限制

写这题的时候一直在考虑如何限制每次合并的堆数在l~r这个范围内,最后也没搞出来,事实上,只需要在合并一堆的时候限制条件就行了,因为所有k>2的情况都是由k=1的情况得出的,所以在都初始化为inf的情况下,不能合成1堆,dp[i][j][1]=inf,那么后面所有由dp[i][j][1]推出的情况也是inf

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e3 + 100;

bool dp[maxn][maxn];
char str[maxn], str1[maxn], str2[maxn];

int main()
{
    while(~scanf("%s %s %s", str1, str2, str)) {
        int len1 = strlen(str1), len2 = strlen(str2), len = strlen(str);

        if(len1 + len2 != len) {
            printf("No\n");
            continue;
        }
        memset(dp, false, sizeof(dp));

        dp[0][0] = 1;
        for(int i = 0; i <= len1; i++) {
            for(int j = 0; j <= len2; j++) {

                 if(i - 1 >= 0)
                 dp[i][j] |= (dp[i - 1][j] && (str1[i - 1] == str[i - 1 + j]));
                 if(j - 1 >= 0)
                 dp[i][j] |= (dp[i][j - 1] && (str2[j - 1] == str[i + j - 1]));
            }

        }

        if(dp[len1][len2]) printf("Yes\n");
        else printf("No\n");
    }
}

猜你喜欢

转载自blog.csdn.net/deerly_/article/details/80356455