1. 程式人生 > >【LG5020】[NOIP2018]貨幣系統

【LG5020】[NOIP2018]貨幣系統

noip har += pan urn sin 式表 pri getch

【LG5020】[NOIP2018]貨幣系統

題面

洛谷

題解

考場上第一眼還不會233
可以發現只要可以被其他的貨幣通過一些奇奇怪怪的方式表示出來的貨幣就\(ban\)掉即可
就是個完全背包
我是統計的方案數,用\(unsigned\) \(long\) \(long\)防炸\(int\)
就算炸掉了無符號長整型也可能對

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits> 
using namespace std;
inline int gi() {
    register int data = 0, w = 1;
    register char ch = 0;
    while (ch != '-' && !isdigit(ch)) ch = getchar();
    if (ch == '-') w = -1, ch = getchar();
    while (isdigit(ch)) data = data * 10 + ch - '0', ch = getchar();
    return w * data; 
}
#define MAX_N 105
#define MAX_V 25005 
int N, a[MAX_N]; 
unsigned long long dp[MAX_V];
#define RG register 
void solve() {
    dp[0] = 1; 
    for (RG int i = 1; i <= N; i++) {
        for (RG int j = a[i]; j <= a[N]; j++) dp[j] += dp[j - a[i]]; 
    } 
} 
int main () {
    int T = gi();
    while (T--) {
        N = gi(); for (int i = 1; i <= N; i++) a[i] = gi();
        sort(&a[1], &a[N + 1]);
        N = unique(&a[1], &a[N + 1]) - a - 1; 
        memset(dp, 0, sizeof(dp));
        solve(); 
        int ans = N; 
        for (int i = 1; i <= N; i++) if (dp[a[i]] > 1) ans--;
        printf("%d\n", ans); 
    } 
    return 0; 
} 

【LG5020】[NOIP2018]貨幣系統