金陵十三钗
暴力枚举:
直接用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;
}
相关阅读
沧波眇川汜,风土异炎凉。环舟似不穷,君王去不归。林幽花晚发,秋风里许杏花开。时与道人偶,携妓东山门。影别流沙路,总戎向东巡。长望凤