在计算机界中,咱们老是追求用有限的资源获取最大的收益。css
如今,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。数组
你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每一个 0 和 1 至多被使用一次。spa
状态转移方程:dp[i][j]=(dp[i-s_k_zeros][j-s_k_ones]+1, dp[i][j]);code
int findMaxForm(vector<string>& strs, int m, int n) { vector<vector<int>> dp(m+1,vector(n+1,0)); for(string& s : strs){ vector<int> cnt = count(s); int zeros=cnt[0],ones=cnt[1]; for(int i=m;i>=zeros;i--) for(int j=n;j>=ones;j--){ dp[i][j]=max(dp[i-zeros][j-ones]+1,dp[i][j]); } } return dp[m][n]; } vector<int> count(string& s){ int z=0,o=0; for(int i=0;i<s.length();i++){ if(s[i]=='0')z++; else o++; } return {z,o}; }
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。如今你有两个符号 + 和 -。对于数组中的任意一个整数,你均可以从 + 或 -中选择一个符号添加在前面。orm
返回能够使最终数组和为目标数 S 的全部添加符号的方法数。blog
这道题基本上是本身独立思考想出来的啊哈哈哈哈哈哈游戏
状态转移方程:dp[i][j]=max(dp[i-1][j-nums[i]]+dp[i-1][j+nums[i]],dp[i][j]);leetcode
int findTargetSumWays(vector<int>& nums, int S) { int n=nums.size(); int low=0,up=0; for(int i=0;i<nums.size();i++){ low-=nums[i]; up+=nums[i]; } if(S<low||S>up)return 0; vector<vector<int>> dp(n,vector<int>(4020,0)); dp[0][nums[0]+1000]++;dp[0][1000-nums[0]]++; for(int i=1;i<n;i++){ for(int j=S+2000;j>=0;j--){ if(j>=nums[i]) dp[i][j]=max(dp[i-1][j-nums[i]]+dp[i-1][j+nums[i]],dp[i][j]); else dp[i][j]=max(dp[i-1][j+nums[i]],dp[i][j]); } } return dp[n-1][S+1000]; }
咱们正在玩一个猜数游戏,游戏规则以下:资源
我从 1 到 n 之间选择一个数字,你来猜我选了哪一个数字。字符串
每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了。
然而,当你猜了数字 x 而且猜错了的时候,你须要支付金额为 x 的现金。直到你猜到我选的数字,你才算赢得了这个游戏
用动态规划列举猜想的全部状况,每次划分的左右两个区间内,假设正确的数字在代价更大的那个区间,找到有最小代价的划分元素。
int getMoneyAmount(int n) { vector<vector<int>> dp(n+1,vector<int>(n+1,0)); for(int len=2;len<=n;len++){ for(int start=1;start<=n-len+1;start++){ int mas=INT_MAX; for(int i=start;i<start+len-1;i++){ int t=i+max(dp[start][i-1],dp[i+1][start+len-1]); mas=min(mas,t); } dp[start][start+len-1]=mas; } } return dp[1][n]; }
待续。。。