一 原题
Burch, Kolstad, and Schrijvers
Farmer John is trying to erect a fence around part of his field. He has decided on the shape of the fence and has even already installed the posts, but he's having a problem with the rails. The local lumber store has dropped off boards of varying lengths; Farmer John must create as many of the rails he needs from the supplied boards.
Of course, Farmer John can cut the boards, so a 9 foot board can be cut into a 5 foot rail and a 4 foot rail (or three 3 foot rails, etc.). Farmer John has an `ideal saw', so ignore the `kerf' (distance lost during sawing); presume that perfect cuts can be made.
The lengths required for the rails might or might not include duplicates (e.g., a three foot rail and also another three foot rail might both be required). There is no need to manufacture more rails (or more of any kind of rail) than called for the list of required rails.
PROGRAM NAME: fence8
INPUT FORMAT
Line 1: | N (1 <= N <= 50), the number of boards |
Line 2..N+1: | N lines, each containing a single integer that represents the length of one supplied board |
Line N+2: | R (1 <= R <= 1023), the number of rails |
Line N+3..N+R+1: | R lines, each containing a single integer (1 <= ri <= 128) that represents the length of a single required fence rail |
SAMPLE INPUT (file fence8.in)
4 30 40 50 25 10 15 16 17 18 19 20 21 25 24 30
OUTPUT FORMAT
A single integer on a line that is the total number of fence rails that can be cut from the supplied boards. Of course, it might not be possible to cut all the possible rails from the given boards.SAMPLE OUTPUT (file fence8.out)
7
二 分析
三 代码
USER: Qi Shen [maxkibb3] TASK: fence8 LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 4192 KB] Test 2: TEST OK [0.000 secs, 4192 KB] Test 3: TEST OK [0.000 secs, 4192 KB] Test 4: TEST OK [0.000 secs, 4192 KB] Test 5: TEST OK [0.000 secs, 4192 KB] Test 6: TEST OK [0.000 secs, 4192 KB] Test 7: TEST OK [0.000 secs, 4192 KB] Test 8: TEST OK [0.000 secs, 4192 KB] Test 9: TEST OK [0.000 secs, 4192 KB] Test 10: TEST OK [0.000 secs, 4192 KB] Test 11: TEST OK [0.000 secs, 4192 KB] Test 12: TEST OK [0.000 secs, 4192 KB] All tests OK.
Your program ('fence8') produced all correct answers! This is your submission #3 for this problem. Congratulations!
/*
ID:maxkibb3
LANG:C++
PROB:fence8
*/
#include<cstdio>
#include<algorithm>
const int MAX_BOARD = 55;
const int MAX_RAIL = 1024;
int n, m, board[MAX_BOARD], rail[MAX_RAIL];
int boardsum, railsum[MAX_RAIL];
int curwaste, maxwaste, cutfrom[MAX_RAIL];
void init() {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &board[i]);
boardsum += board[i];
}
scanf("%d", &m);
for(int i = 0; i < m; i++)
scanf("%d", &rail[i]);
std::sort(rail, rail + m);
railsum[0] = rail[0];
for(int i = 1; i < m; i++)
railsum[i] = railsum[i - 1] + rail[i];
}
bool dfs(int index) {
if(curwaste > maxwaste) return false;
if(index < 0) return true;
int st = 0;
if(rail[index] == rail[index + 1])
st = cutfrom[index + 1];
for(int i = st; i < n; i++) {
if(board[i] < rail[index]) continue;
board[i] -= rail[index];
cutfrom[index] = i;
if(board[i] < rail[0]) curwaste += board[i];
bool flag = dfs(index - 1);
if(board[i] < rail[0]) curwaste -= board[i];
cutfrom[index] = 0;
board[i] += rail[index];
if(flag) return true;
}
return false;
}
void solve() {
int l = 0, r = m;
while(l < r) {
int mid = l + ((r - l + 1) >> 1);
maxwaste = boardsum - railsum[mid - 1];
if(dfs(mid - 1)) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
}
int main() {
freopen("fence8.in", "r", stdin);
freopen("fence8.out", "w", stdout);
init();
solve();
return 0;
}