1.如果目标数字是x,那么假设它拆分出来的两个部分a和b,如果a==b,那么x的所有位数的和是2a,2a必然是偶数,所以目标各位数字的和必然为偶数,奇数必然拆分不了,输出No
2.按位拆分数字x,将它每一位数按顺序排成数组,数组长度是n,数组的和是t,要想把t拆分成相等的两半,数组的一半必然是一个整数,设为half,如果有一个数大于half,那么必然拆分不了,输出No,如果有一个数等于half,那么数组必然能直接拆分成两半
3.如果以上情况都不成立,那么只能求n个数里取m个数,使m个数的和为half,即变形的背包问题
假设有数组dp,表示和为0~half的目标是否能达成,dp[j]表示和为j的目标是否能达成,存在为True,不存在为False,数组有一个数字是i,遍历dp数组,那么dp[j+i]取决于dp[j]是否能达成,如果能达成,则dp[i+j]一定能达成,即dp[i+j] = dp[j],以此不断更新dp
a = input()
al = [int(x) for x in list(a)]  # 拆分每一位,转成数组
t = sum(al)  # 对每一位进行求和

if t % 2:
    print('No')  # 如果所有数字的和是奇数,那么它一定不存在两个子集和等于它
else: 
    half = t // 2 # 数字和的一半,也就是凑和为half的背包,剩下的自然是另一个背包
    flag = 0 # 判断是否可以结束循环
    dp = [False for i in range(half + 1)] # 和为0-half的状态表,若m能实现,则dp[m]=True
    for i in al:

        if i > half:  # 如果有一个数大于一半,那么这个目标一定达不成
                print('No')
                flag = 1
                break
        elif i == half:  # 如果有一个数刚好等于一半,那么这个目标已经达成
                print('Yes')
                flag = 1
                break
        else:
            dp_copy = dp.copy()  # 不能直接更新dp,否则会导致重复累加
            for j in range(0, half + 1):
                if i + j <= half and dp[j]:  # 当前数字是i,如果目标j,即dp[j]可以实现,那么目标i+j,即dp[i+j]一定可以实现
                    dp_copy[j + i] = True
                elif i + j > half:
                    break
            dp = dp_copy
            dp[i] = True  # 目标为i则可以直接达成

    if not flag: # 如果前面已经输出完了这里就不再输出了
        print('Yes' if dp[half] else 'No')