列表

详情


DP59. 数位染色

描述

小红拿到了一个正整数 。她可以将其中一些数位染成红色。然后她想让所有染红的数位数字之和等于没染色的数位数字之和。
她不知道能不能达成目标。你能告诉她吗?

输入描述

一个正整数 

输出描述

如果小红能按要求完成染色,输出"Yes"。否则输出"No"。

示例1

输入:

1234567

输出:

Yes

说明:

将3、4、7染成红色即可,这样3+4+7=1+2+5+6

示例2

输入:

23

输出:

No

说明:

显然无论如何都不能完成染色。

原站题解

C++ 解法, 执行用时: 3ms, 内存消耗: 316KB, 提交时间: 2021-09-08

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main()
{
    ll n;
    cin>>n;
    vector<int> num;
    while(n)
    {
        num.push_back(n%10);
        n/=10;
    }
    int sum = accumulate(num.begin(),num.end(),0);
    if(sum%2==1)
    {
        cout<<"No";
        return 0;
    }
    vector<int> dp(sum/2+1,0);
    dp[0]=1;
    for(int i=0;i<num.size();i++)
    {
        for(int j=sum/2;j>=num[i];j--)
        {
            dp[j]=dp[j]+dp[j-num[i]];
        }
    }
    if(dp[sum/2])
        cout<<"Yes";
    else 
        cout<<"No";
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 396KB, 提交时间: 2022-06-19

#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main() {
    long x;
    cin >> x;
    vector<int> vec;
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    int sum = accumulate(vec.begin(), vec.end(), 0);
    if (sum % 2) {
        cout << "No" << endl;
        return 0;
    }
    int target = sum / 2;
    int n = vec.size();
    vector<bool> dp(target + 1, 0);
    dp[0] = 1;
    for (int i = 0; i < n; ++i) {
        for (int j = target; j >= 0; --j) {
            if (vec[i] <= j) {
                dp[j] = dp[j] || dp[j - vec[i]];
            }
        }
    }
    if (dp[target]) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;   
    }
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 396KB, 提交时间: 2022-06-04

#include<bits/stdc++.h>

using namespace std;
int dp[2020];
int main(){
    int n,sum=0,a,maxf=0;
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
       a=(int)(s[i]-'0');
       if(a>maxf){
           maxf=a;
       }
       sum+=a;
    }
    if(sum%2==1)
        cout<<"No";
    else{
        dp[0]=1;
     for(int i = 0; i < s.size(); i++){
        for(int j = sum / 2; j >= (int)(s[i]-'0'); j--)
            dp[j] = dp[j] + dp[j - (int)(s[i]-'0')]; //能够被这两个数相加得到
     }
         if(dp[sum / 2]) //不为0
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    }
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 396KB, 提交时间: 2021-11-02

#include<iostream>
#include<vector>
using namespace std;

int main(){
    long long n;
    cin >> n;
    vector<int> num; //记录数每位
    int sum = 0;
    while(n){ //连除法取每位数字
        sum += n % 10; //求所有位数字累加和
        num.push_back(n % 10);
        n /= 10; 
    }
    if(sum % 2){ //数位和为奇数,无法分成两半
        cout << "No" << endl;
        return 0;
    }
    vector<int> dp(sum / 2 + 1, 0);
    dp[0] = 1;
    for(int i = 0; i < num.size(); i++){
        for(int j = sum / 2; j >= num[i]; j--)
            dp[j] = dp[j] + dp[j - num[i]];
    }
    if(dp[sum / 2])
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 400KB, 提交时间: 2022-07-19

#include<bits/stdc++.h>

using namespace std;

int main(){
    long long x;
    cin>>x;
    vector<int> nums;
    int sum = 0;
    while(x){
        sum += x%10;
        nums.push_back(x%10);
        x /= 10;
    }
    if(sum%2){
        cout<<"No";
        return 0;
    }
    int target = sum/2;
    vector<int> dp(target+1, 0);
    dp[0] = 1;
    for(int i=0;i<=nums.size();i++){
        for(int j=target;j>=nums[i];j--){
            dp[j] = dp[j] + dp[j-nums[i]];
        }
    }
    if(dp[target]){
        cout<<"Yes"<<endl;
    }else{
        cout<<"No"<<endl;
    }
    return 0;
}

上一题