Team Match

版权声明:转载请注明出处,欢迎讨论,共同进步,QQ:1051780721 https://blog.csdn.net/ACM2017/article/details/82260883

题目描述

The programming competition not only depends on the programmers, but also directed by the coaches. Mr Z is a coach who direct n players to take part in the Guangxi Province Collegiate Programming Contest. We assume that a team is consisted of 3 players whose ability is x, y, z respectively and x >= y >= z. Then the team’s total ability is 3 * x + 2 * y + 1 * z; And for a team, if its ability is not lower than the gold medal level m, the team will certainly win the gold medal. Mr Z would like to match teams to gain as many gold medals as possible, could you tell him how many gold medals it is?

输入

The first line is an integer T which indicates the case number.
And as for each case, there will be 2 lines.
In the first line, there are 2 integers n m, which indicate the number of players, the gold medal level respectively. Please remember n is always the multiple of 3.
In the second line, there are n integers which represents everyone’s ability.
It is guaranteed that——
T is about 100.
for 100% cases, 1 <= n <= 15, 1 <= m <= 30, 1 <= a[i] <= 20.

输出

As for each case, you need to output a single line.
There should be an integer in the line which means the gold medal teams Mr Z could match.

样例输入

2
6 18
3 3 3 4 2 2
6 7
1 1 1 1 1 1

样例输出

2
0

Solution

听说这题可以贪心?
……
不会贪心,一时想不到。
算了一下大暴搜是 C 15 2 C 13 2 C 3 2 =15*7*6*11*9*4*3*5*3≈1e7的复杂度,再加剪枝也就过了
这次复杂度算对了……

#include <bits/stdc++.h>
using namespace std;
const int MX=20;
int n,m,a[MX],x,ans;
int l,r,p;
bool vis[MX],Lin[MX][MX][MX];
bool cmp(int A,int B) {
    return A>B;
}
void dfs(int sum) {
    ans=max(ans,sum);
    if(ans==n/3) return;
    int cnt=0,ii=0,res=0;
    while (cnt<3) {
        while (vis[ii]) ii++;
        res+=a[ii]*(3-cnt);
        cnt++;
        ii++;
    }
    if (res<m) return;
    int i,j,k,x;
    for (i=0;i<n-2;++i)
        if (!vis[i]) {
            vis[i]=true;
            for (j=i+1;j<n-1;++j)
                if (!vis[j]) {
                    vis[j]=true;
                    k=n-1;
                    x=m-a[i]*3-a[j]*2;
                    while ((vis[k]||a[k]<x)&&k>j) k--;
                    if (k>j) {
                        vis[k]=true;
                        //printf("(%d,%d,%d) ",i,j,k);
                        dfs(sum+1);
                        vis[k]=false;
                    }
                    vis[j]=false;
                }
            vis[i]=false;
        }
}
int main() {
    int T,i,j,k;
    scanf("%d",&T);
    while (T--) {
        scanf("%d%d",&n,&m);
        ans=0;
        for (int i=0; i<n; ++i) scanf("%d",&a[i]);
        sort(a,a+n,cmp);
        for (i=0; i<n-2; ++i)
            for (j=i+1; j<n-1; ++j) {
                x=m-3*a[i]-2*a[j];
                for (k=n-1; k>j; --k) if (a[k]>=x) break;
                if (a[k]>=x&&k>j) {
                    vis[i]=vis[j]=vis[k]=true;
                    //printf("(%d,%d,%d) ",i,j,k);
                    dfs(1);
                    //printf("\n");
                    vis[i]=vis[j]=vis[k]=false;
                }
            }
        printf("%d\n",ans);
    }
    return 0;
}

/**************************************************************
    Problem: 7136
    User: St085
    Language: C++
    Result: 正确
    Time:8 ms
    Memory:1708 kb
****************************************************************/

猜你喜欢

转载自blog.csdn.net/ACM2017/article/details/82260883