POJ 1787 Charlie ' s change Backpack series + Journey record
At first glance. Multiple backpacks.
Again at first sight. convert 01 backpack? NoNoNo, the quantity of each item reaches the 10^4, certainly will t.
Again at first sight. I can't see it. Go and see Daniel's puzzle.
Oh--turn it into a full backpack.
How do you turn? The general full backpack is unlimited number. Now every time we enumerate the items, we record how many are taken and then limit the number.
Well..
Journey record words full backpack plus a path record father. Then a multi-pack plus a num array is calculated directly at DP. See the code specifically: The full backpack of that version of the path record feeling very clever AH hey
The conversion equation is still old ...
F[I][J] represents the optimal solution for the value K obtained with the first I coins
It is transferred only when the last state is up (not 0).
The state equation is:
F[I][J] = F[i-1][j-val[i]] + 1; (F[i-1][j-val[i] > 0 && f[i-1][j] < F[i][j-val[i]] + 1)
Complete backpack plus a num[j-val[i]] + 1 <= limit[i],num is the number of the current use of the type I, limit when I kind of available quantities.
And then we roll the array and scroll to optimize the space.
。。 Why is this the right thing to do?
We start from small coins to traverse.
If the solution is the least ...
It's good to start with a big coin ... "The above are my mouth-hu
Slag Code:
1#include <iostream>2#include <string.h>3#include <math.h>4#include <algorithm>5#include <stdlib.h>6#include <stdio.h>7 #definell Long Long8 using namespacestd;9 Const intN =10010;Ten intF[n], N, Path[n], c[5], val[5] = {0,1,5,Ten, -}, ans[n][5]; One voidZeroOne (intValintNumintPOS) A { - for(inti = n; I >= Val; I--){ - if(F[i-val] && f[i-val] + num >F[i]) { theF[i] = F[i-val] +num; - for(intj =1; J <=4; J + +){ -ANS[I][J] = ans[i-Val] [j]; - } +Ans[i][pos] + =num; - } + } A } at voidCompleteintValintPOS) - { - for(inti = Val; I <= N; i + +){ - if(F[i-val] && F[i-val] +1>F[i]) { -F[i] = F[i-val] +1; - for(intj =1; J <=4; J + +){ inANS[I][J] = ans[i-Val] [j]; - } toAns[i][pos] + =1; + } - } the } * voidMultiintNumintValintPOS) $ {Panax Notoginseng if(Num * val >=N) { -Complete (val, POS);return ; the } + intTMP =1; A while(Num >=tmp) { theZeroOne (TMP *val, tmp, POS); +num-=tmp; -TMP <<=1; $ } $ if(num) zeroone (num *val, num, POS); - } - intMain () the { - while(~SCANF ("%d%d%d%d%d", &n, &c[1], &c[2], &c[3], &c[4]) && n + c[1] + c[2] + c[3] + c[4]){Wuyimemset (ans,0,sizeof(ans)); thememset (Path,0,sizeof(path)); -Memset (F,0,sizeof(f)); Wuf[0] =1; - for(inti =1; I <=4; i + +){ About multi (C[i], val[i], i); $ } - if(!F[n]) { -printf"Charlie cannot buy coffee.\n");Continue; - } Aprintf"Throw in%d cents,%d nickels,%d dimes, and%d quarters.\n", ans[n][1],ans[n][2],ans[n][3],ans[n][4]); + } the return 0; -}
Multiple Backpack
1#include <iostream>2#include <string.h>3#include <math.h>4#include <algorithm>5#include <stdlib.h>6#include <stdio.h>7 #definell Long Long8 using namespacestd;9 Const intN =10010;Ten intF[n], N, Path[n], c[5], val[5] = {0,1,5,Ten, -}, ans[ -], num[n]; One intMain () A { - while(~SCANF ("%d%d%d%d%d", &n, &c[1], &c[2], &c[3], &c[4]) && n + c[1] + c[2] + c[3] + c[4]){ -memset (ans,0,sizeof(ans)); thememset (Path,0,sizeof(path)); -Memset (F,0,sizeof(f)); -f[0] =1; - for(inti =1; I <=4; i + +){ +memset (NUM,0,sizeof(num)); - for(intj = Val[i]; J <= N; J + +){ + if(F[j-val[i] && F[j-val[i]] +1> F[j] && num[j-val[i]] +1<=C[i]) { AF[J] = F[j-val[i]] +1; atNUM[J] = Num[j-val[i]] +1; -PATH[J] = J-Val[i]; - } - } - } - if(!F[n]) { inprintf"Charlie cannot buy coffee.\n");Continue; - } to while(N >0){ +Ans[n-path[n]] + +; -n =Path[n]; the } *printf"Throw in%d cents,%d nickels,%d dimes, and%d quarters.\n", ans[1],ans[5],ans[Ten],ans[ -]); $ }Panax Notoginseng return 0; -}
Full Backpack
Here are two ways to run out of time compared to the last one. The top is a full backpack, the following is a multi-pack.
Done.
------------------------------
POJ 1787 Charlie ' s change