C. Chino with Queue 【状压DP】【牛客】【2019西北工业大学程序设计创新实践基地春季选拔赛】

现在有n个人排成一队(2<=n<=18)

给你一个n*n的矩阵

Wij代表 i在j的前面的话   i给j带来多大的舒适度

如果i排在最前面 前面没有人的话 则带来Wii的舒适度

所以现在要你问你 怎么排 可以排出 最大舒适度的队伍 求最大舒适度是多少

题解:

由于n并不大 那么我们可以用一个0 ---- (1<<18 - 1)的范围表示当前有哪些队伍已经排好了

即状压DP思想

我们可以开一个 dp[1<<18][19]  表示dp[当前的状态][当前状态的最后一位为多少]  所得到的舒适度

AC_code:

#include <iostream>
#include <algorithm>
using namespace std;

int dp[1<<18][20];
int w[20][20];
int main() {
	int n;
	cin>>n;
	for(int i=0; i<n; ++i) {
		for(int j=0; j<n; ++j) {
			cin>>w[i][j];
		}
	}
	// 为0表示没进去队列 为1表示已经进去了队列  
	for(int i=0; i<(1<<n); ++i) {
		for(int j=0; j<n; ++j) {
			if((i&(1<<j))==0) {//i 第j位为0
				if(i==0) dp[i|(1<<j)][j]=max(dp[i|(1<<j)][j],w[j][j]);   // i为0     i|(1<<j)把i的第j位化为1 
				else {// i不为为0     i|(1<<j)把i的第j位化为1 
					for(int k=0; k<n; ++k) {
						if((i&(1<<k))==0) continue;  // i的第k位为 0   
						dp[i|(1<<j)][j]=max(dp[i|(1<<j)][j],dp[i][k]+w[j][k]);  
					}
				}
			}
		}
	}
	int ans=-1;
	for(int i=0; i<n; ++i) {
		ans=max(dp[(1<<n)-1][i], ans);
	}
	cout<<ans<<endl;
	return 0;
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值