CF1316E. Team Building

https://codeforces.com/contest/1316/problem/E

E. Team Building

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Alice, the president of club FCB, wants to build a team for the new volleyball tournament. The team should consist of pp players playing in ppdifferent positions. She also recognizes the importance of audience support, so she wants to select kk people as part of the audience.

There are nn people in Byteland. Alice needs to select exactly pp players, one for each position, and exactly kk members of the audience from this pool of nn people. Her ultimate goal is to maximize the total strength of the club.

The ii-th of the nn persons has an integer aiai associated with him — the strength he adds to the club if he is selected as a member of the audience.

For each person ii and for each position jj, Alice knows si,jsi,j  — the strength added by the ii-th person to the club if he is selected to play in the jj-th position.

Each person can be selected at most once as a player or a member of the audience. You have to choose exactly one player for each position.

Since Alice is busy, she needs you to help her find the maximum possible strength of the club that can be achieved by an optimal choice of players and the audience.

Input

The first line contains 33 integers n,p,kn,p,k (2≤n≤105,1≤p≤7,1≤k,p+k≤n2≤n≤105,1≤p≤7,1≤k,p+k≤n).

The second line contains nn integers a1,a2,…,ana1,a2,…,an. (1≤ai≤1091≤ai≤109).

The ii-th of the next nn lines contains pp integers si,1,si,2,…,si,psi,1,si,2,…,si,p. (1≤si,j≤1091≤si,j≤109)

Output

Print a single integer resres  — the maximum possible strength of the club.

Examples

input

Copy

4 1 2
1 16 10 3
18
19
13
15

output

Copy

44

input

Copy

6 2 3
78 93 9 17 13 78
80 97
30 52
26 17
56 68
60 36
84 55

output

Copy

377

input

Copy

3 2 1
500 498 564
100002 3
422332 2
232323 1

output

Copy

422899

Note

In the first sample, we can select person 11 to play in the 11-st position and persons 22 and 33 as audience members. Then the total strength of the club will be equal to a2+a3+s1,1a2+a3+s1,1.

 

用状压DP记录遍历到第i个人时的所有状态,但是有些人要当观众。必须记录观众的大小关系。利用贪心思想对观众得分从大到小排序,再按此顺序遍历。这样前面的人如果不当选手,那必定当观众。

 

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	
	void work() {
		int n=ni(),p=ni(),k=ni();
		long[] A=na(n);
		long[][] B=new long[n][];
		for(int i=0;i<n;i++) {
			B[i]=na(p);
		}
		Integer[] rec=new Integer[n];
		for(int i=0;i<n;i++)rec[i]=i;
		Arrays.sort(rec,new Comparator<Integer>() {
			public int compare(Integer a,Integer b) {
				return (int)(A[b]-A[a]);
			}
		});
		long[] dp=new long[1<<p];
		Arrays.fill(dp, -1);
		dp[0]=0;
		for(int i=0;i<n;i++) {
			int idx=rec[i];
			long[] ndp=dp.clone();
			for(int j=0;j<1<<p;j++) {
				if(dp[j]==-1)continue;
				int c=0;
				for(int l=0;l<p;l++) {
					if(((1<<l)&j)>0) {
						c++;
					}
				}
				int r=k-(i-c);//i代表已用人数,c代表选手,因为从大到小排列,多出来的人肯定不当观众
				if(r>0) {//当观众
					ndp[j]=Math.max(ndp[j],dp[j]+A[idx]);
				}
				for(int l=0;l<p;l++) {
					if(((1<<l)&j)==0) {
						ndp[j|(1<<l)]=Math.max(ndp[j|(1<<l)],dp[j]+B[idx][l]);
					}
				}
			}
			dp=ndp;
		}
		out.println(dp[(1<<p)-1]);
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}
	
	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}	

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}


	public String next() 
	{
		while(st==null || !st.hasMoreElements())//回车,空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值