Description
Tingting wants to draw and stucco N squares with N different colors full of the base line of a wall.
Give you the number of squares, the length of the wall, the minimum size and the maximal size of each square and the price of stuccoing one centiare of the wall with a special color. Your task is to calculate the minimum cost.
Input
For each case, the first line is two integers, N, L(1 <= N <= 5, 1 <= L <= 200), N is the number of squares that tingting wants to draw, L is the total length of the wall. The second line is N positive floating numbers, the I-th number of this line means the price of stuccoing one centiare of the wall with I-th color. Then N lines follow, Each line contains two integers, MinI, MaxI(1 <= MinI <= MaxI <= L), which indicates the size of I-th square. For simplify, you can assume that all the sizes of squares are integers. Certainly you should also realize that you can paint each square with the color you like, but each color can only be used once.
Output
Output the minimum cost, one line percase, if he can‘t draw the requirement squares, just output "Impossible".
Sample Input
2 5
1.0 2.0
1 5
1 5
2 5
1.0 2.0
3 4
3 4
Sample Output
17.000题意:给定n个限定了边长范围的正方形,现在要把它们全部铺到长度固定,高度不限的墙上,一共有N种颜色,告诉每种颜色的单位面积价格。问铺满墙的最少开销是多少?只要长度为L的墙被覆盖了所有长度即可。
思路:DP,设f[i][j][k]表示到第i个长度为j颜色选k时的最小开销,其中k表示状态,每次枚举到第i个的时候,状态k1表示的颜色的个数一定要是i-1个,这样才能转移
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 205; const int inf = 0x3f3f3f3f; int n, k; int bit[50], L[10], H[10]; double f[205][50]; double pri[10]; int get(int x) { int cnt = 0; for (int i = 0; i < 5; i++) if (x & (1<<i)) cnt++; return cnt; } void init() { for (int i = 0; i < 40; i++) bit[i] = get(i); } void solve() { for (int i = 0; i <= k; i++) for (int j = 0; j <= 31; j++) f[i][j] = inf; f[0][0] = 0; for (int i = 1; i <= n; i++) { for (int j = k; j >= L[i]; j--) { for (int p = L[i]; p <= j && p <= H[i]; p++) { for (int l = 0; l <= 31; l++) { if (bit[l] != i-1 || f[j-p][l] == inf) continue; for (int h = 0; h < n; h++) if (!(l & (1 << h))) f[j][l|(1<<h)] = min(f[j][l|(1<<h)], f[j-p][l] + p*p*pri[h+1]); } } } } if (f[k][(1<<n)-1] == inf) printf("Impossible\n"); else printf("%.3lf\n", f[k][(1<<n)-1]); } int main() { init(); while (scanf("%d%d", &n, &k) != EOF) { for (int i = 1; i <= n; i++) scanf("%lf", &pri[i]); for (int i = 1; i <= n; i++) scanf("%d%d", &L[i], &H[i]); solve(); } return 0; }
原文:http://blog.csdn.net/u011345136/article/details/39968817