#include <cstdio> #include <vector> #include <cstring> using namespace std; #define MAX_INT 0x7fffffff typedef struct _stat { int money; int cnt; }ST_STAT; int cas, n, m, x; ST_STAT stat[10010]; vector<ST_STAT> v_larger; /* 在大于n的集合中查找最小值 */ void find_min() { ST_STAT min; min.money = MAX_INT; min.cnt = MAX_INT; vector<ST_STAT>::iterator beg, end; end = v_larger.end(); for (beg = v_larger.begin() ; beg != end ; beg++) { if (beg->money < min.money) min = *beg; else if (beg->money == min.money) { if (beg->cnt < min.cnt) { min = *beg; } } } printf("%d %d\n", min.money, min.cnt); } void dp(int size) { int i, j, k, idx; ST_STAT temp; for (i=0 ; i<size ; i++) { scanf("%d", &x); /* 从后向前寻找最优值,如果从前往后的话,更新的值会覆盖原值(背包中也用过类似的思路) */ for (j=n-1 ; j>=0 ; j--) { if (-1 == stat[j].money) continue; idx = x + stat[j].money; /* 钱数已经超过n,将其加入到vector中,等待后面在v中寻找最优值 */ if (idx >= n) { temp.money = idx; temp.cnt = stat[j].cnt + 1; v_larger.push_back(temp); continue; } /* 这个钱数以前已经出现过,看是否需要更新 */ if (-1 != stat[idx].money) { if (stat[j].cnt + 1 < stat[idx].cnt) { stat[idx].cnt = stat[j].cnt + 1; } } /* 这个值没有出现过,直接更新 */ else { stat[idx].money = idx; stat[idx].cnt = stat[j].cnt + 1; } } /* printf("stat:"); for (k=0 ; k<n ;="" k++) { printf("%d %d, ", stat[k].money, stat[k].cnt); } printf("\n"); */ } find_min(); } int main(int argc, char *argv[]) { int i; scanf("%d", &cas); while (cas--) { scanf("%d", &n); scanf("%d", &m); memset(stat, 0, sizeof(stat)); v_larger.clear(); for (i=1 ; i<=n ; i++) stat[i].money = -1; stat[0].money = stat[0].cnt = 0; dp(m); } } |