89 k数和
原题网址:https://www.lintcode.com/problem/k-sum/description
描述
给定n个不同的正整数,整数k(k < = n)以及一个目标数字。
在这n个数里面找出K个数,使得这K个数的和等于目标数字,求问有多少种方案?
样例
给出[1,2,3,4],k=, target=,[1,4] and [2,3]是个符合要求的方案
dp[i][j][t]=dp[i-][j][t];
if (t>=A[i])//注意是大于等于;
{
dp[i][j][t]+=dp[i-][j-][t-A[i]];
}
意思就是,每个元素都有两种状态,取或者不取:
(1)若不取A[i]这个值,当前方案数等于从前i-1个数中取j个使其和为t的方案数,即dp[i - 1][j][t]。
(2)若取当前值A[i],则当前方案数等于从前i-1个数中取j个使其和为t的方案数再加上考虑A[i]的情况,即dp[i - 1][j - 1][t - A[i]](前提是t - A[i]要大于等于0)。
class Solution {
public:
/**
* @param A: An integer array
* @param k: A positive integer (k <= length(A))
* @param target: An integer
* @return: An integer
*/
int kSum(vector<int> &A, int k, int target) {
// write your code here
int size=A.size();
if (target<)
{
return ;
}
vector<vector<vector<int>>> dp(size+,vector<vector<int>>(k+,vector<int>(target+,))); for (int i=;i<=size;i++)
{
for (int j=;j<=k;j++)
{
for (int t=;t<=target;t++)
{
if (j==&&t==)//前i个数中取0个和为0只有一种方案,就是不取任何数;
{
dp[i][j][t]=;
}
else if (!(i==||j==||t==))
{
dp[i][j][t]=dp[i-][j][t];
if (t>=A[i-])//注意是大于等于;
{
dp[i][j][t]+=dp[i-][j-][t-A[i-]];
}
}
}
}
}
return dp[size][k][target]; }
};
class Solution {
public:
/**
* @param A: An integer array
* @param k: A positive integer (k <= length(A))
* @param target: An integer
* @return: An integer
*/
int kSum(vector<int> &A, int k, int target) {
// write your code here
int size=A.size();
if (target<)
{
return ;
}
vector<vector<int>> dp(k+,vector<int>(target+,));
dp[][]=;
for (int i=;i<=size;i++)
{
for (int j=k;j>=;j--)
{
for (int t=target;t>=;t--)
{
if (!(i==||j==||t==))
{
if (t>=A[i-])//注意是大于等于;
{
dp[j][t]+=dp[j-][t-A[i-]];
}
}
}
}
}
return dp[k][target]; }
};
int kSum2(vector<int> &A, int k, int target)
{
int size=A.size();
if (target<)
{
return ;
}
vector<vector<int>> dp(k+,vector<int>(target+,));
dp[][]=; for (int i=;i<=size;i++)//注意此处下标范围与下面A下标对应;
{
for (int j=k;j>;j--)
{
for (int t=target;t>;t--)
{
if (t>=A[i-])//注意是大于等于;
{
dp[j][t]+=dp[j-][t-A[i-]];
}
}
}
}
return dp[k][target];
}
还有更简洁的版本:
class Solution {
public:
/**
* @param A: an integer array.
* @param k: a positive integer (k <= length(A))
* @param target: a integer
* @return an integer
*/
int kSum(vector<int> A, int k, int target) {
// wirte your code here T(n, k, target) = O(n*k*target). area(n, k, target) = O(k*target)
int n = A.size();
int dp[k+][target+];
memset(dp, , sizeof(dp));
dp[][] = ;
for (int x = ; x < n; x++)
for (int y = k; y >= ; y--)
for (int z = target; z >= A[x]; z--)
dp[y][z] += dp[y-][z-A[x]];
return dp[k][target];
}
};
优化成二维dp后,i的遍历可以从0~size-1,也可以从1~size,并不影响结果,就是要注意与A下标对应,前者是A【i】,后者是A【i-1】。因为最初始的那张表是dp【0】【0】=1,其他位置都为0。循环开始后,数组A中每个元素都对应一个二维表,计算过程就是用当前二维表不断代替上一状态的二维表。
class Solution {
public:
/**
* @param A: An integer array
* @param k: A positive integer (k <= length(A))
* @param target: An integer
* @return: An integer
*/
int kSum(vector<int> &A, int k, int target) {
// write your code here
int result=;
if (A.empty())
{
return result;
}
ksum(A,k,target,,,,result);
return result;
} void ksum(vector<int> &A, int k, int target,int sum,int ind,int size,int &result)
{
if (size==k)
{
if (sum==target)
{
result++;
}
return ;
}
if (ind>=A.size())
{
return ;
}
ksum(A,k,target,sum+A[ind],ind+,size+,result);
ksum(A,k,target,sum,ind+,size,result);
} };
89 k数和的更多相关文章
- lintcode 中等题:k Sum ii k数和 II
题目: k数和 II 给定n个不同的正整数,整数k(1<= k <= n)以及一个目标数字. 在这n个数里面找出K个数,使得这K个数的和等于目标数字,你需要找出所有满足要求的方案. 样例 ...
- [LeetCode]Median of Two Sorted Arrays 二分查找两个有序数组的第k数(中位数)
二分.情况讨论 因为数组有序,所以能够考虑用二分.通过二分剔除掉肯定不是第k位数的区间.如果数组A和B当前处理的下标各自是mid1和mid2.则 1.假设A[mid1]<B[mid2], ①.若 ...
- 90 k数和 II
原题网址:https://www.lintcode.com/problem/k-sum-ii/description 描述 Given n unique integers, number k (1&l ...
- K数和问题
问题描述 给定n个不同的正整数(数组num),整数k(k < = n)以及一个目标数字target.在这n个数里面找出k个数,使得这k个数的和等于目标数字,求问有多少种方案? 解决思路 该类问题 ...
- 220. Contains Duplicate III 数组指针差k数值差t
[抄题]: Given an array of integers, find out whether there are two distinct indices i and j in the arr ...
- 陕西师范大学第七届程序设计竞赛网络同步赛D ZQ的睡前故事【约瑟夫环1-N数到第k个出队,输出出队顺序/ STL模拟】
链接:https://www.nowcoder.com/acm/contest/121/D来源:牛客网 题目描述 ZQ是一个拥有n女朋友的万人迷,她的每一个女朋友每天晚上都会挨个给他打电话,要他讲了睡 ...
- lintcode:快乐数
快乐数 写一个算法来判断一个数是不是"快乐数". 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是 ...
- Project Euler 92:Square digit chains 平方数字链
题目 Square digit chains A number chain is created by continuously adding the square of the digits in ...
- [AGC005D] ~K Perm Counting [dp]
题面 传送门 思路 首先可以明确的一点是,本题中出现不满足条件的所有的数,都是分组的 只有模$K$意义下相同的数之间才会出现不满足条件的情况,而且仅出现在相邻的情况 那么我们考虑把这个性质利用起来 我 ...
随机推荐
- ps-使用通道抠图为XX换背景
第一步先载入图片 点击通道,复制蓝色通道 然后点击新的蓝色通道,图像-调整-曲线-改变输入输出, 然后用历史画笔全部填黑. 然后载入选区,复制.在图层中新建蒙版 黏贴,反向(CTRL+I)就可以了. ...
- [JSOI2019]精准预测
题目 这么明显的限制条件显然是\(\text{2-sat}\) 考虑按照时间拆点,\((0/1,x,t)\)表示\(x\)个人在时间\(t\)是生/死 有一些显然的连边 \[(0,x,t+1)-> ...
- Python中虚拟环境venv的基本用法
环境windows 7 venv为python3中的默认库,无需安装. 创建新的venv方法, 在当前文件夹下执行cmd,输入如下代码 python -m venv bob bob为需要创建的文件夹名 ...
- 【JZOJ6370】基础 fake 练习题
description 装饰者坐在树荫下听着长者讲述以前的故事: 大神 yk 非常喜欢树,便钦点班里的 n 个小蒟蒻站在一棵 n 个点以 1 为根的树上,并且每个点上恰好有 1 个小蒟蒻. 大神 yk ...
- js对象 事件
对象 创建 var myObject = {};/* 声明对象字面变量*/ 添加值myObject.name="Jener";myObject.age=25; 代码格式 ...
- 全球轮3——cf1148
c——贪心构造题 /* 1 [n/2+1,n] 2 [n/2+2,n] ... n/2 [n,n] n/2+1 [1,1] n/2+2 [1,2] ... n [1,n/2] ai要换到位置ai上,用 ...
- docker企业级镜像仓库harbor
第一步:安装docker和docker-compose 第二步:下载harbor-offine-installer-v1.5.1.tgz 第三步:上传到/opt,并解压 第四步:修改harbor.cf ...
- Censored! POJ - 1625 AC自动机+大数DP
题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...
- Input:type属性
1.button:定义可点击的按钮(通常与 JavaScript 一起使用来启动脚本). <input id="" type="button" name= ...
- vue表格之tableHeaderColor(修改表头背景色)
<el-table :header-cell-style="tableHeaderColor"></el-table> // 更改表头样式 tableHea ...