hrbust1818 石子合并问题--直线版 (经典区间DP)

求解的大问题是在区间[1, n]内合并石子的最优值,石子分成两个区间[1,k][k+1,n]。不断地将大区间分成小区间。

设dpmax[i][j]表示i堆石子到j堆石子合并得到的最大分数,dpmin[i][j]表示i堆石子到j堆石子合并得到的大小分数,num[i][j]表示i堆石子到j堆石子的总数

状态转移方程:
dpmax[i][j]=max{dp[i][k]+dp[k+1][j]+num[i][j]} k在区间[i, j-1]内
dpmin[i][j]=min{dp[i][k]+dp[k+1][j]+num[i][j]} k在区间[i, j-1]内
3.初始化:dpmax[i][i]=0;dpmin[i][j]=0;就是说一堆石子没办法和相邻的石子合并

#include
#include
#include
using namespace std;
#define clr(x) memset(x,0,sizeof(x))
#define INF 0x1f1f1f1f
long long fmax[105][105];
long long fmin[105][105];
long long a[105];
long long sum[105];
long long num[105][105];
int n,i,j,len,k;
int main(){
    while(scanf("%d",&n)!=EOF){
        clr(sum);
        clr(fmax);
        memset(fmin,INF,sizeof(fmin));
        int tot=0;
        for(i=1;i<=n;i++){
           scanf("%lld",&a[i]);
           tot=tot+a[i];
           sum[i]=tot;
        }
        for(i=1;i<=n;i++)
        for(j=i;j<=n;j++){
            num[i][j]=sum[j]-sum[i-1];
        }
        //f[i][j]=f[i+k]+f[k+1][j]+num[i][j]
        for(i=1;i<=n;i++)
        fmin[i][i]=0,fmax[i][i]=0;
        for(len=1;len



你可能感兴趣的:(基础DP)