【數論】B052_吉祥數(BE / 01 dp(未 AC))

一、Problem

如果一個數的十進制各位能夠被分爲兩個集合,並且這兩個集合裏的數的和相等,我就認爲是吉祥數。而吉祥數的個數則意味着我們的默契度。現在給你兩個數 l,rl,r,你能告訴我 l,l+1rl,l+1…r 中有幾個數是吉祥數嗎?

輸入

輸入兩個數l和r。

輸出

輸出 l,l+1rl,l+1…r 中吉祥數的個數。

11 20
1

990 5930
1158

在這裏插入圖片描述

二、Solution

方法一:BE

  • BE 得到每一個 [l,r][l, r] 的每一個子集 A,那麼 A 肯定存在一個補集 B。
  • 我們將這兩個集合的累加和求出來,記錄到 sum1 和 sum2 中。
  • 如果 sum1 = sum2,返回 true 即可…

留下 30/100 超時的淚水…😂

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		boolean check(int n) {
			char[] s = (n + "").toCharArray();
			int N = s.length, tot = 1 << N;
			for (int i = 0; i < tot; i++) {
		        int s1 = 0, s2 = 0;
				for (int j = 0; j < N; j++) {
					if ((i & (1 << j)) > 0) s1 += s[j] - '0';
					else                    s2 += s[j] - '0';
				}
				if (s1 == s2)
				    return true;
			}
			return false;
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			int l = sc.nextInt(), r = sc.nextInt(), res = 0;
			for (int i = l; i <= r; i++) {
				if (check(i))
					res++;
			}
			System.out.println(res);
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:rl2i\sum_{r}^{l}2^i,比預算要快…
  • 空間複雜度:O(1)O(1)

方法二:01 dp

  • 定義狀態
    • dp[i]dp[i] 表示總和爲 ii 的狀態可達。
  • 思考狀態轉移方程
    • dp[i]=dp[i]dp[iw[i]]dp[i] = dp[i] | dp[i-w[i]] 表示兩個狀態其一到達 dp[i]dp[i] 就說明 dp[i]dp[i] 可達。
  • 思考初始化:
    • dp[0]=1dp[0] = 1,表示總和 0 的狀態不需要選數字就能達到。
  • 思考輸出dp[sum]dp[sum]

再次留下超時的淚水…🤣

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			int l = sc.nextInt(), r = sc.nextInt(), res = 0;
			for (int k = l; k <= r; k++) {
				int sum = 0, t = k;
				List<Integer> all = new ArrayList<>();
				while (t > 0) {
					int bit = t % 10;
					all.add(bit);
					sum += bit;
					t /= 10;
				}
				if (sum % 2 != 0)
					continue;
				boolean[] dp = new boolean[sum+1];
				dp[0] = true;
				sum >>= 1;
				for (int i = 0; i < all.size(); i++) {
					for (int j = sum; j >= all.get(i); j--)
						dp[j] = dp[j] | dp[j-all.get(i)];
				}
				if (dp[sum]) res++;
			}
			System.out.println(res);
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(12N)O(\sum_{1}^{2}N)
  • 空間複雜度:O(n)O(n)

目前沒有找到可 ac 的思路,望仙人指路…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章