描述
小红拿到了一个正整数 x 。她可以将其中一些数位染成红色。然后她想让所有染红的数位数字之和等于没染色的数位数字之和。
她不知道能不能达成目标。你能告诉她吗?
输入描述:
一个正整数 x ,1≤x≤10^18
输出描述:
如果小红能按要求完成染色,输出”Yes”。否则输出”No”。
0-1背包问题
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include <iostream> #include <vector> #include <functional> using namespace std;
int main() { long long x; cin>>x; string tmp=to_string(x); int n=tmp.length(); int sum=0; for(auto ch:tmp){ sum+=(ch-'0'); } if(sum%2){ cout<<"No"<<endl; return 0; } vector<vector<int>> memo(n,vector<int>(sum/2+1,-1)); function<int(int,int)> dfs=[&](int i,int c)->int{ if(i<0){ return c==0; } int& ret=memo[i][c]; if(ret!=-1) return ret; if(c<(tmp[i]-'0')){ return ret=dfs(i-1,c); } return ret=dfs(i-1,c)+dfs(i-1,c-(tmp[i]-'0')); }; if(dfs(n-1,sum/2)){ cout<<"Yes"<<endl; }else{ cout<<"No"<<endl; } return 0; }
|
给你一个非负整数数组 nums 和一个整数 target 。
向数组中的每个整数前添加 ‘+’ 或 ‘-‘ ,然后串联起所有整数,可以构造一个 表达式 :
- 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-‘ ,然后串联起来得到表达式 “+2-1” 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
0-1背包
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: int findTargetSumWays(vector<int>& nums, int target) { target+=accumulate(nums.begin(),nums.end(),0); if(target<0||target%2==1){ return 0; } int m=target/=2;
int n=nums.size(); vector<vector<int>> memo(n,vector<int>(m+1,-1)); function<int(int,int)> dfs=[&](int i,int c)->int{ if(i<0) return c==0; int& ret=memo[i][c]; if(ret!=-1) return ret; if(c<nums[i]){ return ret=dfs(i-1,c); } return ret=dfs(i-1,c)+dfs(i-1,c-nums[i]); }; return dfs(n-1,m); } };
|
描述
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,
每种面值的货币可以使用任意张, 再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
数据范围:数组大小满足 0≤n≤10000 , 数组中每个数字都满足 0<val≤10000, 0≤aim≤5000
要求:时间复杂度 O(n×aim) ,空间复杂度 O(aim)。
完全背包问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public: int minMoney(vector<int>& arr, int aim) { int n=arr.size(); if(n==0){ return -1; } vector<vector<int>> memo(n,vector<int>(aim+1,-1)); function<int(int,int)>dfs=[&](int i,int c)->int{ if(i<0){ return c==0?0:INT_MAX/2; } int&ret=memo[i][c]; if(ret!=-1) return ret; if(c<arr[i]){ return ret=dfs(i-1,c); } return ret=min(dfs(i-1,c),dfs(i,c-arr[i])+1); }; int ans=dfs(n-1,aim); return ans<INT_MAX/2?ans:-1; } };
|