COCI CONTEST #1 18.10.2014 T5 ZABAVA

第五题:学生宿舍
新的学生宿舍开放了,它由M栋建筑物构成,标号为1到M。开始时,学生宿舍都是空的,很快有N个学生搬进去了。刚好每天搬进去一个。
每次有新同学搬进宿舍,那栋建筑将会举行一个大型的party。party的噪声和该建筑物里的学生的数量相等。宿舍管理员不喜欢噪声,所以他们会不定期的清空某栋建筑物。清空的方法就是把该栋建筑物的学生全部赶到另外的学生宿舍(这M栋宿舍以外的地方)。但是管理员最多只能清空K次。求这n天噪音之和的最小值。
输入格式:
第一行三个整数n,m,k。(1<=n<=1000000,1<=m<=100,1<=k<=500)
接下来有n行,每行一个整数bi(1<=bi<=m),表示第i天有一个学生搬进了bi栋宿舍。
输出格式:一个整数,表示这n天噪音之和的最小值。
40%的数据m=1
60%的数据n<=1000
80%的数据n<=50000
输入样例1:
5 1 2
1
1
1
1
1
输出样例1:
7

输入样例2:
11 2 3
1
2
1
2
1
2
1
2
1
2
1
输出样例2:
18

样例1解释:在第一天和第三天之后执行清空操作。这样每天的噪声为1,1,2,1,2,所以噪声之和为7.
样例2解释:对建筑物1在第4天和第8天执行清空操作,对建筑物2在第6天之后执行清空操作,这样每天的噪声分别为1,1,2,2,1,3,2,1,1,2,2,噪音之和为18.

一般难度的题,过了5/7.
考试的时候想到正解了,就是有些细节没考虑好。
首先我们考虑当m=1的时候。
清空操作肯定是要在平均一些的地方清空。
比如说有5个学生,清空1次。
有以下几个清空情况:
1 1 2 3 4
1 2 1 2 3
1 2 3 1 2
1 2 3 4 1
显然在2,3那里清空比较好。
这里就是一个贪心。
然后我们来考虑m比较大的情况。
就是有很多宿舍,你需要分配一种清空操作使得总和最小。
于是写出DP方程:f[i][j]=f[i-1][k]+cal(i,j-k).
解释:对前i个宿舍进行j次清空操作的噪音值,就是对前i-1个宿舍进行k次清空操作的噪音值+对i这个宿舍进行j-k次清空操作的噪音值

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,k,len,tot,cnt[105],h[105];
long long f[105][505];//注意开long long
bool vis[105];
inline void GET(int &a)//学校机子跑得慢,加个读入优化才能过233
{
    a=0;
    char c,f=1;
    do{c=getchar();if(c=='-')f=-1;}while(c>'9'||c<'0');
    while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}
    a=a*f;
}
inline long long cal(long long x,long long y)//第x个宿舍清理y次
{
    y++;
    if(y>cnt[x])return 0x3f3f3f3f;
    long long t=cnt[x]/y,p=cnt[x]%y;
    return (t+1)*(t+2)/2*p+t*(t+1)/2*(y-p);
}
int main()
{
    memset(f,0x3f,sizeof f);
    GET(n);
    GET(m);
    GET(k);
    for(int i=1;i<=n;++i)
    {
        int t;
        GET(t);
        cnt[t]++;
        if(!vis[t])h[++tot]=t;//注意这里宿舍标号要离散化,因为有可能他住在1,3,5,7,9间= =,然后就转移不过来
        vis[t]=1;
    }
    for(int i=0;i<=k;++i)//边界条件
        f[h[1]][i]=cal(h[1],i);
    for(int i=2;i<=tot;++i)//dp
        for(int j=0;j<=k;++j)
            for(int p=0;p<=j;++p)
                f[h[i]][j]=min(f[h[i]][j],f[h[i-1]][p]+cal(h[i],j-p));
    printf("%I64d\n",f[h[tot]][k]);
}

你可能感兴趣的:(COCI CONTEST #1 18.10.2014 T5 ZABAVA)