比赛 |
20120614 |
评测结果 |
AAWWAWAAWA |
题目名称 |
工作指派 |
最终得分 |
60 |
用户昵称 |
ZhouHang |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2012-06-14 16:31:12 |
显示代码纯文本
/**
*Prob : dividea
*Data : 2012-6-14
*Sol : 动归+决策单调性
*Author : Zhou Hang
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lld long long
#define MaxN 100100
using namespace std;
int n,k,c;
lld f[MaxN],a[MaxN];
lld min(lld x,lld y)
{
if (x<y) return x;
return y;
}
lld Sqr(int x)
{
return (lld)x*x;
}
lld cal(int x,int y)
{
return f[x]+c+Sqr(a[y]-a[x+1]);
}
//朴素
int dp1()
{
memset(f,127,sizeof(f));
f[0]=0;
for (int i=1; i<k; i++)
f[i]=cal(0,i);
for (int i=k; i<=n; i++)
for (int j=0; j<=i-k; j++)
f[i]=min(f[i],cal(j,i));
printf("%I64d\n",f[n]);
}
//决策单调性
int dp2()
{
memset(f,127,sizeof(f));
f[0]=0;
for (int i=1; i<k; i++)
f[i]=cal(0,i);
int head=0,tmp;
for(int i=k; i<=n; i++)
{
tmp=head;
for(int j=tmp; j<=i-k; j++)
if( f[i]>=cal(j,i) )
{
f[i]=cal(j,i);
tmp=j;
}
head=tmp;
}
printf("%I64d\n",f[n]);
}
int main()
{
freopen("dividea.in","r",stdin);
freopen("dividea.out","w",stdout);
scanf("%d%d%d",&n,&k,&c);
for (int i=1; i<=n; i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
if (n<=9000) dp1();
else dp2();
fclose(stdin); fclose(stdout);
return 0;
}