神仙开山(进制状压DP)

题目

描述 Description
神仙姐姐来到一个美丽的地方,不过美中不足的是那儿有好些秃山……
由于神仙过于爱美,由不得有半点瑕疵,所以她想用仙力把这些儿秃山通通消灭掉!由于消灭一座山可能要消耗掉一些Hp Or Mp Or Rp……但是有的时候不必考虑那么多,你有可能只需要考虑HP和MP,甚至仅仅考虑HP.(难道是请了哪位俊男来帮忙…….?)
输入格式 Input Format
第一行有两个整数n (0<n<=100)和m (1<=m<=5),分别表示山的数量和需要考虑的身体数值种类.
第二行m个整数 v1—vm,表示神仙各种数值的初始值(各种数值消耗后不会回复);
第三行到第n+2行,分别是这n座山的资料,每行m+1个数。每行第一个数是消灭掉这座山可以得到的美观度,第二到第m+1个数分别表示消灭掉这座山消耗的各种数值(对应第二行的数值)
输出格式 Output Format
输出神仙姐姐可以得到的最大美观度(每种数值最后不可消耗到<0);

题解

  • 首先很容易想到这道题一种暴力的解法,因为题中的 m ⩽ 5 m\leqslant5 m5,那么我们很容易想到开一个五维的 F F F数组进行01背包,但这无疑会造成很大的空间浪费。
  • 那么我们就想到的状态压缩。
  • 如果这道题只有一维,那就十分容易,可如果他有两维,我们就需要思考一下。
  • 假设这两维中每一维中最大的数字分别为 a , b a, b a,b,那么他们所能表示的最大的一维数字即为 ( a + 1 ) ∗ ( b + 1 ) − 1 (a+1)*(b+1)-1 (a+1)(b+1)1
  • 那么我们推广到 n n n维来看
  • 设这几个进制数为 t 1 , t 2 , t 3 , ⋯ &ThinSpace; , t n t_1, t_2, t_3, \cdots, t_n t1,t2,t3,,tn,转化为 10 10 10进制对应的数为 m 1 , m 2 , m 3 , ⋯ &ThinSpace; , m n m_1,m_2,m_3,\cdots,m_n m1,m2,m3,,mn
  • 那么 m i = ∏ k = i + 1 n t k + 1 m_i= \prod_{k = i+1}^{n} t_k+1 mi=k=i+1ntk+1
  • 这样的话我们就能将题中所给的 m m m转化为一个十进制数了,在我们状态压缩过后,题目就变成了一道简单的背包问题。

code


const int maxn = 105;
const int maxm = 1e5 + 100;
const int inf = 0x3f3f3f3f;

int n;
int m;
int num;
int v[maxn];
int t[maxn];
int p[maxn];
int f[maxm];
int weigh[maxn];
int w[maxn][maxn];

int main() {
	read(n), read(m); // 快读
	for (int i = 1; i <= m; ++i)
		read(p[i]);
	t[1] = 1;
	for (int i = 2; i <= m + 1; ++i)
		t[i] = t[i - 1] * (p[i - 1] + 1);
	num = t[m + 1] - 1;
	for (int i = 1; i <= n; ++i) {
		read(v[i]);
		for (int j = 1; j <= m; ++j) {
			read(w[i][j]);
			weigh[i] += w[i][j] * t[j];
		}
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = num; j >= weigh[i]; j--) {
			int k;
			for (k = 1; k <= m; ++k)
				if (j % t[k + 1] / t[k] < w[i][k]) break;
			if (k > m)
				f[j] = max(f[j], f[j - weigh[i]] + v[i]);
		}
	}
	write(f[num]); // 快写
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值