状压dp-基础题目2([USACO12MAR] Cows in a Skyscraper G)

题目链接

做题反思

这题我一开始没过Subtask #1,当时想的是dp数组存储电梯承载奶牛集合s(二进制转整数)需要的最少趟数,再开一个数组z,存储奶牛集合s的重量,如果zs>w,则让zs%w。这是不对的,比如Subtask #1的数据最大载重w为10,4头奶牛的重量为9,9,9,2,用这个思路,答案是3。问题就在于这种做法会把奶牛"分身"乘坐电梯,比如前两头奶牛,有一头奶牛会有1重量在1趟电梯,另外8重量在另一趟电梯,这就有问题了。

题目正解
  • 数组定义
    我们定义一个数组dp,dpij表示第i趟运送奶牛集合j的重量。初始化dp数组为0x3f3f3f3f,dp00=0,dp11\<\<(i-1)=ci
  • 状态转移
    外层遍历趟数,循环遍历为i,范围是1至n。内层循环遍历集合j,范围0至(1<<n),我们看一下用i趟运送奶牛集合j是否能实现,如果可以,则再遍历新加入奶牛,循环变量k,范围是1至n。通过移位运算和与运算判断集合j时候有奶牛k,如果没有就看一下当前dpij+ck是否大于w,如果是,要新开一趟,dpi+1j\|(1\<\<(k-1))=min(dpi + 1j \| (1 \<\< k - 1),ck);否则, dpij \| (1 \<\< k - 1) = min(dpij \| (1 \<\< k - 1), dpij + ck)。
  • 输出答案
    循环变量i遍历1至n,输出第一个dpi(1\<\<0x3f3f3f3f的值,结束。
AC代码
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int w, c[20], dp[20][1 << 20], n;

int main() {
	cin >> n >> w;
	memset(dp, 0x3f, sizeof(dp));
	dp[0][0] = 0;
	for (int i = 1; i <= n; i++) {
		cin >> c[i];
		dp[1][1 << (i - 1)] = c[i];
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < (1 << n); j++) {
			if (dp[i][j] < 0x3f3f3f3f) {
				for (int k = 1; k <= n; k++) {
					if (!((1 << k - 1)&j)) {
						if (dp[i][j] + c[k] > w)
							dp[i + 1][j | (1 << k - 1)] = min(dp[i + 1][j | (1 << k - 1)], c[k]);
						else
							dp[i][j | (1 << k - 1)] = min(dp[i][j | (1 << k - 1)], dp[i][j] + c[k]);
					}
				}
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (dp[i][(1 << n) - 1] < 0x3f3f3f3f) {
			cout << i;
			break;
		}
	}
	return 0;
}
相关推荐
choumin3 小时前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
云小逸3 小时前
【SVN 详细使用指南:从入门到团队协作】
c++·svn
徐小夕4 小时前
花了一周,3亿tokens,我开源了一款 Word 文档智能审查平台,文稿自动质检+可视化分析,告别低效人工审核
前端·算法·github
可编程芯片开发6 小时前
UPFC统一潮流控制器的simulink建模与仿真
算法
小小仙子6 小时前
矢量网络分析仪如何测试S参数的?
人工智能·算法·机器学习
中微极客8 小时前
降维算法75倍加速:从PCA到稀疏字典学习的工程实践
人工智能·学习·算法
storyseek8 小时前
前缀和实现Kogge-Stone算法
数据结构·算法
ziguo11228 小时前
深入浅出 C/C++ 数据类型:从入门到踩坑
linux·c语言·c++·windows·visual studio
元Y亨H9 小时前
开发者必须掌握的十大核心算法
算法