字面意思:以区间为下标的dp
总纲:
题目1:https://www.luogu.org/problemnew/show/P1880#sub
注意:这是个环!!!复制一遍即可
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxSize=200,maxValue=0x7fffffff;
int n;
int a[maxSize+5],f1[maxSize+5][maxSize+5],f2[maxSize+5][maxSize+5],sum[maxSize+5][maxSize+5];
void dp()
{
int i,j,k,min1=maxValue,max1=0;
for (i=1;i<n;i++) //区间大小
{
for (j=0;i+j<2*n;j++)//起始位置
{
for (k=j;k<i+j;k++)//中间插入位置
{
f1[j][i+j]=min(f1[j][i+j],f1[j][k]+f1[k+1][i+j]+sum[j][i+j]);
f2[j][i+j]=max(f2[j][i+j],f2[j][k]+f2[k+1][i+j]+sum[j][i+j]);
}
}
}
for (i=0;i<=n;i++)
{
min1=min(min1,f1[i][i+n-1]);
max1=max(max1,f2[i][i+n-1]);
}
printf("%d\n%d\n",min1,max1);
}
int main()
{
int i,j,k;
freopen("a.txt","r",stdin);
scanf("%d",&n);
for (i=0;i<n;i++)
scanf("%d",&a[i]);
for (i=0;i<2*n;i++)
for (j=i;j<=2*n;j++)
{
f1[i][j]=maxValue;
f2[i][j]=0;
}
for (i=0;i<2*n;i++)
{
f1[i][i]=0;
f2[i][i]=0;
}
for (i=0;i<n;i++)
for (j=0;j<2*n;j++)
for (k=j;k<=i+j;k++)
{
if (k>=n)
sum[j][i+j]+=a[k-n];
else
sum[j][i+j]+=a[k];
}
dp();
return 0;
}
题目2:https://www.luogu.org/problemnew/show/P1854#sub
一次ac
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxSize=100;
int F,v;
int f[maxSize+5][maxSize+5],a[maxSize+5][maxSize+5],f1[maxSize+5][maxSize+5],ans[maxSize+5];
void dp()
{
int i,j,k,max1,max2;
for (i=2;i<=F;i++)
{
for (j=i;j<=v-F+i;j++)
{
for (k=i-1;k<j;k++)
{
if (f[i][j]<f[i-1][k]+a[i][j])
{
f[i][j]=f[i-1][k]+a[i][j];
f1[i][j]=k;
}
}
}
}
max1=0;
for (i=F;i<=v;i++)
if (max1<f[F][i])
{
max1=f[F][i];
ans[F]=i;
}
printf("%d\n",max1);
for (i=F-1;i>0;i--)
{
ans[i]=f1[i+1][ans[i+1]];
}
for (i=1;i<=F;i++)
printf("%d ",ans[i]);
}
int main()
{
int i,j;
freopen("a.txt","r",stdin);
scanf("%d%d",&F,&v);
for (i=1;i<=F;i++)
for (j=1;j<=v;j++)
scanf("%d",&a[i][j]);
memset(f,0,sizeof(f));
for (i=1;i<=v-F+1;i++)
f[1][i]=a[1][i];
dp();
return 0;
}
3.题目:https://www.luogu.org/problemnew/show/P1006#sub
注意&& ||
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxSize=50;
int m,n;
int a[maxSize+5][maxSize+5],f[maxSize+5][maxSize+5][maxSize+5][maxSize+5];
int maxium(int i,int j,int k,int l)
{
return max(max(f[i][j][k][l],f[i-1][j][k-1][l]+a[i][j]+a[k][l]),max(f[i][j-1][k][l-1],max(f[i][j-1][k-1][l],f[i-1][j][k][l-1]))+a[i][j]+a[k][l]);
}
void dp()
{
int i,j,k,l;
for (i=1;i<=m;i++)
{
for (j=1;j<=n;j++)
{
for (k=1;k<=m;k++)
{
for (l=1;l<=n;l++)
{
if (i==k && j==l && (i!=m || j!=n))
f[i][j][k][l]=-1;
else
f[i][j][k][l]=maxium(i,j,k,l);
}
}
}
}
printf("%d\n",f[m][n][m][n]);
}
int main()
{
int i,j;
freopen("a.txt","r",stdin);
scanf("%d%d",&m,&n);
for (i=1;i<=m;i++)
{
for (j=1;j<=n;j++)
scanf("%d",&a[i][j]);
}
dp();
return 0;
}