题目
【例5.6】设有A,B,C,D,E五人从事J1,J2,J3,J4,J5五项工作,每人只能从事一项,他们的效益如下。
每人选择五项工作中的一项,在各种选择的组合中,找到效益最高的的一种组合输出。
输入
无输入。
输出
前面五行,输出五人分配的工作;
最后一行输出:supply:最佳效益值。(参考样例输出)
样例输出 复制
A:J5
B:J3
C:J4
D:J1
E:J2
supply:50
做了几个题之后,发现模板1和模板2是真好用,这题直接写出模板1的代码 。
题解
模板1
#include<bits/stdc++.h>
using namespace std;
int ans[10], c[10];
char nb[] = {'A', 'B', 'C', 'D', 'E'};// 根据输出格式的标记数组
int mmp[6][6] = {{0, 13, 11, 10, 4, 7},
{0, 13, 10, 10, 8, 5},
{0, 5, 9, 7, 7, 4},
{0, 15, 12, 10, 11, 5},
{0, 10, 11, 8, 8, 4}};
int sum = 0;
int res = 0;
bool vis[10];
void print(){
for(int i = 0;i < 5;i ++){
cout << nb[i] << ':' << 'J' << c[i] <<'\n';
}
cout << "supply:" << res << '\n';
}
void fcx(int d){//
for(int j = 1;j <= 5;j ++){
if(vis[j])continue;
sum += mmp[d][j];
vis[j] = true;
ans[d] = j;
if(d == 4){
if(sum > res){
res = sum;
memcpy(c, ans, sizeof ans);
}
}else {
fcx(d + 1);
}
vis[j] = false;
sum -= mmp[d][j];
}
}
int main(){
memset(vis, 0, sizeof vis);
fcx(0); // dfs(1)
print();
return 0;
}
模板2
#include<bits/stdc++.h>
using namespace std;
int ans[10], c[10], res, sum;
bool vis[10];
char np[] = {'x', 'A', 'B', 'C', 'D', 'E'};
int mp[6][6] = {{0, 13, 11, 10, 4, 7},
{0, 13, 10, 10, 8, 5},
{0, 5, 9, 7, 7, 4},
{0, 15, 12, 10, 11, 5},
{0, 10, 11, 8, 8, 4}};
void print(){
for(int i = 1;i <= 5;i ++){
cout << np[i] << ':' << 'J' << ans[i] << '\n';
}
cout << "supply:" << res;
}
void fcx(int d){
if(d == 6){
if(sum > res){
res = sum;
memcpy(ans, c, sizeof c);
}
}else {
for(int j = 1;j <= 5;j ++){
if(!vis[j]){
vis[j] = true;
sum += mp[d - 1][j];
c[d] = j;
fcx(d + 1);
sum -= mp[d - 1][j];
vis[j] = false;
}
}
}
}
int main(){
fcx(1);
print();
return 0;
}
奇怪的方法
可以用枚举类似蒙特卡洛模拟的思想来解决
#include<bits/stdc++.h>
using namespace std;
char nb[] = {'A', 'B', 'C', 'D', 'E'};
int mmp[6][6] = {{0, 13, 11, 10, 4, 7},
{0, 13, 10, 10, 8, 5},
{0, 5, 9, 7, 7, 4},
{0, 15, 12, 10, 11, 5},
{0, 10, 11, 8, 8, 4}};
int ans = 0;
int p[10];
void print(){
for(int i = 0;i < 5;i ++){
cout << nb[i] << ":J" << p[i] << '\n';
}
cout << "supply:" << ans << '\n';
}
void randperm(int Num)
{
int res = 0;
vector<int> temp;
for (int i = 0; i < Num; ++i)
{
temp.push_back(i + 1);
}
random_shuffle(temp.begin(), temp.end());
for (int i = 0; i < temp.size(); i++)
{
res += mmp[i][temp[i]];
}
if(res > ans){
ans = res;
for(int i = 0;i < temp.size();i ++){
// cout << temp[i] << ' ';
p[i] = temp[i];
}
// cout <<'\n';
}
}
int main(){
int t = 0;
srand((int)time(0));// 随机数随时间变化
for(int i = 1;i <= 1000;i ++){// 蒙特卡洛思想,可以将i的最大值可以设置小一点,如20,
randperm(5);//运行多次发现,有时过,有时不过。纯随机,看人品
}
print();
return 0;
}