MisakaMKT

模拟赛毒瘤状压DP题:Kronican

Kronican
内存限制:32 MiB
时间限制:2000 ms
标准输入输出
题目类型:传统
评测方式:文本比较
上传者: cqbzgm
题目描述
Mislav有N个无限体积的杯子,每一个杯子中都有一些水。Mislav想喝掉所有的水,但他不想喝超过K杯水。Mistrav能做的就是将一个杯子中的水倒入另一个杯子中。 不幸的是,挑选哪两个杯子进行倒水操作对Mislav来说很重要,因为并非所有的杯子都离他一样远。更准确地说,从i号杯子向j号杯子倒水所付出的代价为Cij。 帮助Mislav找到他需要付出的总代价的最小值。

输入格式
第一行输入包含整数N和K(1≤K≤N≤20)。表示水杯的总数和Mislav最多能喝多少杯。 接下来N行每行包含N个整数Cij(0≤Cij≤1e5)。第i+1行的第j个整数表示从第i个杯子第j个杯子倒水所需要付出的代价。保证Cii等于0。

输出格式
输出一个整数。表示Mislav需要付出的总代价的最小值。

样例
样例输入1
3 3
0 1 1
1 0 1
1 1 0
样例输出1
0
样例输入2
3 2
0 1 1
1 0 1
1 1 0
样例输出2
1
样例输入3
5 2
0 5 4 3 2
7 0 4 4 4
3 3 0 1 2
4 3 1 0 5
4 5 5 5 0
样例输出3
5
数据范围与提示
对于40%的数据,N≤10。

这道题考场上我想到的居然是最小生成树(于是就成功的爆零了),如果加了特判的话就有80分,主要还是数据太水了吧。

下面就来讲讲正解呗,因为之前接触过状压DP,所以做起来还是比较顺。

一个二进制数0000表示4个水杯都装有水,0001表示第一个水杯是空的,代价最小的状态,同理,1000表示第4个水杯是空的,代价最小的状态。

现在来考虑状态转移,拿1000举例,不难发现它可以转移到。

  • 1100
  • 1010
  • 1001
    (可以这么考虑,我们在1000这个状态下进行了一个将i杯子的水倒入了j的操作。不管ij是多少,总会有一个杯子会空掉,所以会多出一个"1"出来)

因为每次操作只能在两个装有水的杯子ij的杯子进行,所以我们只需要在当前状态1000里暴力枚举位数为0ij,模拟将i倒入j的操作。因为i倒入了j,所以第i位为1,权值为wij

那么我们便可以得出状态转移方程:
fS+1<<i=min(fS+wij)

S为当前状态,一个二进制数。当空的杯子,也就是S的1的个数为nk时,我们便可以记录答案。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define N 30

int n,k,w[N][N],ans,inf,f[1<<21];

int main() {
	memset(f,0x3f,sizeof(f));
	ans=f[0];
	cin>>n>>k;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
		cin>>w[i][j];
	f[0]=0;
	for(int S=0;S<1<<n;S++) {
		int sum=0;
		for(int i=1;i<=n;i++) if(S & (1<<(i-1))) sum++;
		if(sum==n-k) {
			ans=min(ans,f[S]);
			continue;
		}
		if(sum>n-k) continue;
		for(int i=1;i<=n;i++)
			if(!(S&(1<<(i-1))))
				for(int j=1;j<=n;j++)
					if(!(S & (1<<(j-1))) && i!=j) 
						f[S+(1<<(i-1))]=min(f[S+(1<<(i-1))],f[S]+w[i][j]);
	}
	cout<<ans;
}

posted on   MisakaMKT  阅读(176)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)

导航

统计信息

点击右上角即可分享
微信分享提示