【蓝桥杯】 金陵十三钗

暴力枚举:

直接用next_pernutation,只能得到70分

#include<bits/stdc++.h>
using namespace std;
int a[20];
int b[20][20];
int main()
{
	int n,ans=0;
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cin>>b[i][j];
	for(int i=1;i<=n;i++)
		a[i]=i;
	do
	{
		int temp=0;
		for(int i=1;i<=n;i++)
			temp+=b[i][a[i]];
		ans=max(ans,temp);
	}while(next_permutation(a+1,a+1+n));
	cout<<ans<<endl;
	return 0;
} 

状压dp

#include<bits/stdc++.h>
using namespace std;
int dp[14][1<<14];//i个人选择状态为j的最大收益 
int a[14][14];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cin>>a[i][j];
	for(int i=1;i<=n;i++)//第i个人 
	{
		for(int j=0;j<(1<<n);j++)//枚举状态 
		{
			for(int k=1;k<=n;k++)//选第k个学生 
			{
				if((j&(1<<k-1))==0)//没有 
					dp[i][j|(1<<k-1)]=max(dp[i][j|(1<<k-1)],dp[i-1][j]+a[i][k]);
			}
		}
	}
	cout<<dp[n][(1<<n)-1]<<endl;
	return 0;
}

DFS加枝减

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const int N = 20;
int g[N][N], p[N];
bool use[N];
int n, ans;
 
void DFS(int d, int s)
{
	if (d > n)
	{
		ans=max(ans, s);
		return;
	}
	for (int i = 1; i <= n; ++i)
		if (!use[i] && s + g[d][i] + p[d + 1] > ans) //如果下面加p仍然不大于答案则不继续
		{
			use[i] = 1;
			DFS(d + 1, s + g[d][i]);
			use[i] = 0;
		}
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			scanf("%d", &g[i][j]);
	for (int i = n; i >= 1; --i)
	{
		int mx = 0;
		for (int j = 1; j <= n; ++j)
			mx=max(mx, g[i][j]);
		p[i] = p[i + 1] + mx; //不限制不同列的最大值前缀
	}
	DFS(1, 0);
	cout << ans << endl;
 
	return 0;
}
发布了119 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_40727946/article/details/90271025
今日推荐