1. 程式人生 > 實用技巧 >pdd(負權01揹包,容斥原理)

pdd(負權01揹包,容斥原理)

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
//         商品數              // 揹包大小
        int n = sc.nextInt(), m = sc.nextInt();
        int[] v = new int[n+1];
        int[] w = new int[n+1];
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            
int val = sc.nextInt(); w[i] = sc.nextInt(); if(val < 0) { // 容量為負直接放入 m -= val; // 擴容 v[i] = -val; ans += w[i];// 放入後要在最後加上它的價值 } else { v[i] = val; } } int[] dp = new int[m+1];
for(int i = 1; i <= n; i++) { for(int j = m; j >= v[i]; j--) { dp[j] = Math.max(dp[j],dp[j-v[i]] + w[i]); } } for(int i = 1; i <= m; i++) { dp[m] = Math.max(dp[m],dp[i]); } System.out.println(dp[m] + ans); } }

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m =sc.nextInt();
        int[] arr = new int[m];
        for(int i = 0; i < m; i++) {
            arr[i] = sc.nextInt();
        }
        int res = 0;
        for(int i = 1; i < 1 << m; i++) {
            int t = 1, cnt = 0;
            for(int j = 0; j < m; j++) {
                if(((i >> j) & 1) != 0) {
                    long add = get(t,arr[j]);
                    if(add > n) {
                        t = -1;
                        break;
                    }
                    t = (int)add;
                    cnt++;
                }
            }
            if(t != -1) {
                if(cnt % 2 == 0) res -= n / t;
                else res += n / t;
            }
        }
        System.out.println(res);
    }

    public static long get(int a, int b) {
        return (long)a * b / gcd(a,b);
    }

    public static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b,a%b);
    }
}