YbtOJ 「动态规划」第2章 区间DP
例题1.石子合并
断环为链,最小值 f1[i][j]=min(f1[i][j],f1[i][k]+f1[k+1][j]+s[j]-s[i-1])
。最大值同理。
code
#include<cstdio>
#include<iostream>
using namespace std;
const int inf=1e9;
int n,a[201],s[201];
int f1[201][201],f2[201][201];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
for(int i=1;i<=2*n;i++) s[i]=s[i-1]+a[i];
for(int i=1;i<=2*n;i++)
for(int j=1;j<=2*n;j++)
f1[i][j]=inf,f2[i][j]=0;
for(int i=1;i<=2*n;i++) f1[i][i]=0,f2[i][i]=0;
for(int l=2;l<=n;l++)
{
for(int i=1;i<=n*2-l+1;i++)
{
int j=i+l-1;
for(int k=i;k<j;k++)
{
f1[i][j]=min(f1[i][j],f1[i][k]+f1[k+1][j]+s[j]-s[i-1]);
f2[i][j]=max(f2[i][j],f2[i][k]+f2[k+1][j]+s[j]-s[i-1]);
}
}
}
int maxn=0,minn=inf;
for(int i=1;i<=n;i++)
{
maxn=max(maxn,f2[i][i+n-1]);
minn=min(minn,f1[i][i+n-1]);
//cout<<"i="<<i<<";minn="<<minn<<endl;
}
cout<<minn<<endl<<maxn<<endl;
return 0;
}
例题2.木板涂色
处理连续刷一段的情况:当前区间两边颜色相同就把答案减去 1。
code
#include<bits/stdc++.h>
using namespace std;
const int N=205;
char s[N];
int n,f[N][N];
int main()
{
scanf("%s",s+1);n=strlen(s+1);
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++) f[i][i]=1;
for(int l=2;l<=n;l++)
{
for(int i=1;i<=n-l+1;i++)
{
int j=i+l-1;
for(int k=i;k<j;k++)
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
if(s[i]==s[j]) f[i][j]--;
}
}
cout<<f[1][n]<<endl;
return 0;
}
本文来自博客园,作者:樱雪喵,转载请注明原文链接:https://www.cnblogs.com/ying-xue/p/16591413.html