U3178 zty的冒险之行
题目提供者mangoyang
题目背景
“妈咪妈咪轰”随着一声巨响,zty传送到了Aluba国,在那里浴血奋战,饱读兵书,风餐露宿,吃喝嫖赌,终于到了先前埋了宝藏的那个神秘地点,只见门前有许多怪物在看守,zty有些心慌,掏出了他的10000 mod 10 美元,“兄弟,你们都是为主办事的,让个道呗” 只见怪物把zty摁在地上,zty卒,复活后,zty决定和怪物决一死战,他发现怪物可以分批打,他想找出一个最优的方案,于是zty找到了学信息学的你来帮忙,由于zty是个土豪,如果你帮他击败怪物,他就给你100000 mod 10 美元
题目描述
放眼望去,这n个怪物排成一排,zty要把这些怪物按照顺序分为m组击破,每个怪物都有一个威慑度a[i],小z面对一组怪物会积累等同改组威慑值最大怪物的威慑值的压抑度,压抑度越大zty越怂,现在请你帮小z找出最小的压抑度之和
输入输出格式
输入格式:
第一行两个数,n,m表示小z要把n个怪物分为m组,接下来一行共n个数,第i个数表示第i个怪物威慑度为a[i]
输出格式:
一个数,即最小的压抑度之和
输入输出样例
输入样例#1:
5 3
1 2 3 4 5
输出样例#1:
8
说明
对于 10%的数据 m=1
对于 100%的数据 n<=100,m<=100
/*
划分型DP.
f[i][j]表示前i个数分成j组的最优值.
从i-1开始扫.
扫一个前k个的最大值作为代表值.
然后f[i][j]=min(f[i][j],f[k][j-1]+max);
转移的时候考虑j-1组+max.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1001
using namespace std;
int s[MAXN],f[MAXN][MAXN],n,m,tot;
int main()
{
memset(f,127/3,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]),f[i][0]=0;;
f[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
tot=s[i];
for(int k=i-1;k>=0;k--)
{
f[i][j]=min(f[i][j],f[k][j-1]+tot);
tot=max(tot,s[k]);
}
}
}
printf("%d",f[n][m]);
}