80 分求助
查看原帖
80 分求助
95624
HPXXZYY楼主2021/2/20 12:18
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
	char c=0;int x=0;bool f=0;
	while (!g(c)) f=c=='-',c=gc;
	while (g(c)) x=x*10+c-48,c=gc;
	return f?-x:x;
}
typedef long long ll;
const ll inf=1e18;//无穷 
const int N=16,M=1e5+100;
ll f[N][(1<<14)+100],c[N];
ll val[N][(1<<14)+100],n,m;
ll a[N][M];bool same[N][N];
vector<ll> b[N];ll fee[N][N];
inline void ckmin(ll &a,ll b){
	a=(b<a?b:a);//让 a 取到 a,b 较小值 
}
int tmp[N],cnt;
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=read();
	for(int i=1;i<=n;i++){
		c[i]=read();//停靠点数量 
		for(int j=1;j<=c[i];j++)
			b[i].push_back(read());
		sort(b[i].begin(),b[i].end());
		for(int j=1;j<=n;j++)
			for(int k=0;k<c[i];k++)
				fee[i][j]+=a[j][b[i][k]];
	}
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++){
			register int u=0,v=0;
			same[i][j]=same[j][i]=true;
			while (u<c[i]&&v<c[j]){
				if (b[i][u]==b[j][v]){
					same[i][j]=same[j][i]=false;
					break;//不能在同一深度 
				}
				if (b[i][u]<b[j][v]) u++;
				else v++;//值小的递增 
			}
		}
	for(int S=1;S<(1<<n);S++){
		memset(tmp,0,sizeof(tmp));
		cnt=0;//一定要记得初始化哦 
		for(int i=1;i<=n;i++)
			if (S&(1<<(i-1)))
				tmp[++cnt]=i;
		register bool flag=true;
		for(int i=1;i<=cnt&&flag;i++)
			for(int j=i+1;j<=cnt;j++)
				if (same[tmp[i]][tmp[j]]==false){
					flag=false;break;
				}
		if (flag){
			for(int i=1;i<=cnt;i++)
				for(int j=1;j<=n;j++)
					val[j][S]+=fee[tmp[i]][j];
		}
		else{
			for(int i=1;i<=n;i++)
				val[i][S]=inf;
		}
	}
	for(int S=1;S<(1<<n);S++)
		f[1][S]=val[1][S];
	for(int i=2;i<=n;i++)
		for(int S=0;S<(1<<n);S++){
			f[i][S]=f[i-1][S];//init
			for(int T=S;T;T=(T-1)&S)
				ckmin(f[i][S],f[i-1][T]+val[i][S^T]);
		}
	printf("%lld",f[n][(1<<n)-1]);
	return 0;
}

仿照出题人 @一扶苏一 的代码写的,但是只有 8080 分。

评测记录

在这里插入图片描述

2021/2/20 12:18
加载中...