题目:http://www.luogu.org/problem/show?pid=2654#
分析:优先队列+DP.
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int Tmax=30,inf=0x3f3f3f3f;
int n,m,k,data[Tmax],f[Tmax][Tmax],ans,ss[Tmax];
priority_queue<int,vector<int>,greater<int> > Q;
void work()
{
int i,j,k,sum=inf;
for(i=1;i<=2*m;i++)
ss[i]=ss[i-1]+data[i];
for(i=2;i<=m;i++)
for(j=1;j<=2*m-i+1;j++)
for(k=1;k<i;k++)
f[i][j]=min(f[i][j],f[k][j]+f[i-k][j+k]+ss[j+i-1]-ss[j-1]);
for(i=1;i<=m;i++)
sum=min(sum,f[m][i]);
ans+=sum;
return;
}
int main()
{
int i,j,a,sum;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++)
{
scanf("%d",&a);
Q.push(a);
}
for(i=1;i<=k;i++)
{
sum=0;
for(j=1;j<=m;j++)
{
scanf("%d",&a);
data[a]=Q.top();
Q.pop();
sum+=data[a];
}
Q.push(sum);
for(j=1;j<=m;j++)
data[m+j]=data[j];
memset(f,0x3f,sizeof(f));
memset(f[1],0,sizeof(f[1]));
ss[0]=0;
work();
}
printf("%d",ans);
return 0;
}