Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Multiple && Complete Pack[转01; 可以不排序]/** * POJ: 3260 The Fewest Coins * * DP: Multiple/Complete Pack * * 此道题的数据__弱__ */ /** ***/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> /** ***/ #define INP 100 #define KND INP * 10 #define T 10000 #define SP T + 10 #define FJ SP #define SUBMIT 1 /** ***/ #define min(a, b) ( (a) < (b) ? (a) : (b) ) #define max(a, b) ( (a) > (b) ? (a) : (b) ) /** ***/ int knd; // kinds of coins(N); int cst; // the total cost(T); int fj[FJ + 1]; // fj[i]: FJ付款i所用的最小coins int sp[SP + 1]; // sp[j]: SP找零j所用的最小coins typedef struct { int val; int cnt; } coin_t; coin_t con[KND + 1]; // 0/1 Pack coin_t inp[INP + 1]; // input /** ***/ int compar(const void *p1, const void *p2) { /* descending order */ return ((coin_t *)p2)->val - ((coin_t *)p1)->val; } /** ***/ int main(int argc, char **argv) { #ifndef SUBMIT freopen("input/3260", "r", stdin); #endif int n; int ans; // the result; int mny; // the maximum coins we study while (2 == scanf("%d%d", &n, &cst)) { /* init */ ans = INT_MAX; knd = mny = 0; memset(fj, 0, sizeof(fj)); memset(sp, 0, sizeof(sp)); /* input */ for (int i = 0; i < n; ++i) { scanf("%d", &inp[i].val); } for (int i = 0; i < n; ++i) { scanf("%d", &inp[i].cnt); } /* convert */ for (int i = 0; i < n; ++i) { if (!inp[i].cnt) { // for CompletePack con[++knd].val = inp[i].val; con[knd].cnt = 0; continue; } for (int k = 1; k < inp[i].cnt; k <<= 1) { con[++knd].val = inp[i].val * k; con[knd].cnt = k; inp[i].cnt -= k; } con[++knd].val = inp[i].val * inp[i].cnt; con[knd].cnt = inp[i].cnt; } /* sort */ qsort(con + 1, knd, sizeof(coin_t), compar); /* dp <-> fj */ for (int i = 1, nt; i <= knd; ++i) { if (!con[i].cnt) { // when (cnt = 0) skip; continue; } for (int j = mny; j >= 0; --j) { if (!fj[j] && j) { // fj[0] === 0; continue; } nt = j + con[i].val; if (nt > T) { /* !!! */ continue; } if (!fj[nt]) { fj[nt] = fj[j] + con[i].cnt; } else { fj[nt] = min(fj[nt], fj[j] + con[i].cnt); } mny = max(mny, nt); } } /* little optimizations */ /* !!! NOT fj[cst] !!! */ if (mny < cst) { printf("-1\n"); continue; } /* dp <-> sp */ for (int i = 1, nt, ct; i <= knd; ++i) { if (!con[i].cnt) { con[i].cnt = 1; } for (int j = 1; j <= mny - cst; ++j) { for (int k = 1; ; ++k) { nt = con[i].val * k; ct = con[i].cnt * k; if (nt > j) { break; } // 求的是__j可以达到时候__的最小值 if (!sp[j - nt] && (j ^ nt)) { continue; } if (!sp[j]) { sp[j] = sp[j - nt] + ct; } else { sp[j] = min(sp[j], sp[j - nt] + ct); } } } } /* resolve */ if (fj[cst]) { ans = min(ans, fj[cst]); } for (int i = cst + 1; i <= mny; ++i) { if (fj[i] && sp[i - cst]) { ans = min(ans, fj[i] + sp[i - cst]); } } /* output */ ans == INT_MAX ? printf("-1\n") : printf("%d\n", ans); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator