我自关山点酒,千秋皆入喉
题目描述:略
思路:这个东西明显就是一个区间的dp,f[i][j]代表抓到第i条蛇,用了j次修改的最优值。(这个题有个坑啊,观察样例可以发现第一次调整网的大小是不算在k次操作里面的呜呜呜。)
下面考虑怎么转移:我们设g[i][j]代表只用一张网抓[i][j]的蛇所花费的空间,然后就可以很容易的写出状态转移方程:
f[i][j]=min(f[i][j],f[t][j-1]+g[t+1][i])
之后就过了QWQ
(这题为什么是蓝题)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int maxn=405;
int n,m,f[maxn][maxn];//f[i][j]代表到i条蛇,用了j次魔法的最优解
int a[maxn],sum[maxn],g[maxn][maxn];//g[i][j]代表第i个蛇到第j个蛇用一只网
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
main(){
n=read();m=read();
sum[0]=0;
m++;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
f[i][j]=1e9+7;
}
}
f[0][0]=0;
for(int i=1;i<=n;i++) a[i]=read(),sum[i]=sum[i-1]+a[i];
for(int i=1;i<=n;i++){
int maxn=0;
for(int j=i;j<=n;j++){
maxn=max(maxn,a[j]);
g[i][j]=maxn*(j-i+1)-sum[j]+sum[i-1];//一网打尽么么哒
}
}
for (int k=1;k<=m;++k)
for (int i=1;i<=n;++i)
for (int j=0;j<=i;++j)
f[i][k]=min(f[i][k],f[j][k-1]+g[j+1][i]);
printf("%lld",f[n][m]);
return 0;
}
//f[i][j]=min(f[i][j],f[t][j-1]+g[t+1][i])