题面POJ 1170:
有诸多商品,没有商品有一个单价。可以组合的买特定个数的特定商品,这样会得到优惠。给出这些优惠策略,给出每种商品的个数,问最少能花多少钱能把这些商品带走?
解:输入好蛋疼,先个商品类型数,然后给每个商品的编号c,个数k,和单价p。再给出s个优惠策略,每种策略前边有一个num,表示需要多少类型的商品组合,然后是num对商品,每对给出商品的编号和数目,最后是固定类型固定数目的商品组合起来需要的花费。
题目说的很清楚,最多5种商品,s最多为99, num最多为5。所以完全可以直接写背包。。。不过这个背包是5维的,写的好蛋疼。。。
dp[i][j][k][l][m]表示背包被i件0号商品,j件1号商品。。。的最小话费,初始化为i*(单价i) + j*(price[j]) + k*(price[k]) + ...
每次转移的时候i, j, k, l, m对这s种优惠策略进行转移。。。取最小
if(i >= t0 && j >= t1 && k >= t2 && l >= t3 && m >= t4) { dp[i][j][k][l][m] = min(dp[i-t0][j-t1][k-t2][l-t3][m-t4] + a[o].p, dp[i][j][k][l][m]); }
代码120+ms。。。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) #define iabs(x) ((x) > 0 ? (x) : -(x)) typedef long long LL; const double eps = 1e-8; const int inf = ~0u>>2; using namespace std; const int N = 110; struct node { int id[6], n[6]; int p, k; } a[N]; struct pnode { int id, n, p; } b[6]; int num[N*10]; int dp[6][6][6][6][6]; int main() { //freopen("data.in", "r", stdin); int t, i, s, x, y; int j, k, l, m, o, p, q; scanf("%d", &t); CL(b, 0); CL(a, 0); for(i = 0; i < t; ++i) { scanf("%d%d%d", &b[i].id, &b[i].n, &b[i].p); num[b[i].id] = i; } scanf("%d", &s); for(i = 0; i < s; ++i) { scanf("%d", &k); a[i].k = 0; while(k--) { scanf("%d%d", &x, &y); a[i].id[a[i].k] = num[x]; a[i].n[a[i].k++] = y; } scanf("%d", &p); a[i].p = p; } int t0, t1, t2, t3, t4; for(i = 0; i <= b[0].n; ++i) { for(j = 0; j <= b[1].n; ++j) { for(k = 0; k <= b[2].n; ++k) { for(l = 0; l <= b[3].n; ++l) { for(m = 0; m <= b[4].n; ++m) { dp[i][j][k][l][m] = i*b[0].p + j*b[1].p + k*b[2].p + l*b[3].p + m*b[4].p; for(o = 0; o < s; ++o) { t0 = t1 = t2 = t3 = t4 = 0; for(q = 0; q < a[o].k; ++q) { if(a[o].id[q] == 0) t0 = a[o].n[q]; if(a[o].id[q] == 1) t1 = a[o].n[q]; if(a[o].id[q] == 2) t2 = a[o].n[q]; if(a[o].id[q] == 3) t3 = a[o].n[q]; if(a[o].id[q] == 4) t4 = a[o].n[q]; } if(i >= t0 && j >= t1 && k >= t2 && l >= t3 && m >= t4) { //printf("%d %d %d %d %d\n", t0, t1, t2, t3, t4); dp[i][j][k][l][m] = min(dp[i-t0][j-t1][k-t2][l-t3][m-t4] + a[o].p, dp[i][j][k][l][m]); } } } } } } } printf("%d\n", dp[b[0].n][b[1].n][b[2].n][b[3].n][b[4].n]); return 0; }