题目来源
学军中学CSP-J2019第二轮A模拟冲剌训练1-day1
地址:XJOI。
题面
学军一年一度的运动会又要开始了。
运动会上一共有m个项目,每个项目最多报2名运动员。
有n个运动员准备参加比赛,每个运动员最多报2个项目。
告诉你每个运动员参加每一个运动的得分。求这些运动员能得到的最大分数。
输入格式
共 n+1 行
第 1 行:n,m 两个整数
第 2~n+1 行:第 i 行 m 个整数,其中第 j 个整数表示第 i 运动员参加第 j 个运动可以得到的得分
输出格式
一个数,表示最大的得分
样例输入
3 2
1 1
2 3
4 5
样例输出
14
数据范围
100%的数据满足:2≤N≤6,2≤M≤6,0≤每个运动员每个项目得分≤10000
题目分析
一个DFS的模板题。就是数据规模比较小。本题贪心应该是错的。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e3+10;
LL a[N][N];//分数
LL book[N];//第i个项目运动员数
bool vis[N][N];
LL ans=0;
LL n;//运动员人数
LL m;//项目数
//idx: 第idx个人
//sum: 当前分数
void dfs(LL idx, LL sum) {
if (idx>n) {
//超过人数
ans=max(ans, sum);
return;
}
//不选这个选手
dfs(idx+1, sum);
//选这个选手,注意每个选手能选2个项目
for (LL i=1; i<=m; i++) {//项目
if (book[i]>=2) {
//该项目超过人数,剪枝
continue;
}
//选第一项目
book[i]++;
dfs(idx+1, sum+a[idx][i]);
book[i]--;
//选第二个项目
for (LL j=i+1; j<=m; j++) {
if (book[j]>=2) {
continue;
}
book[i]++;
book[j]++;
dfs(idx+1, sum+a[idx][i]+a[idx][j]);
book[i]--;
book[j]--;
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for (LL i=1; i<=n; i++) {//运动员
for (LL j=1; j<=m; j++) {//项目
cin>>a[i][j];
}
}
dfs(1, 0);
cout<<ans<<"\n";
return 0;
}