首页 > 试题广场 >

资金匹配

[编程题]资金匹配
  • 热度指数:115 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
现有一笔借款请求(target),借款需要从可用资金列表中(n笔)匹配k笔资金,请问有多少种匹配方案。

例如:借款金额10万,可用资金有8、7、3、2、1,则一共有3种匹配方案,分别(8,2)(7,3)(7,2,1)。

请将上述过程抽象成算法,并实现kSum函数。

说明:
1、n、k均为正整数,且k<=n
2、只考虑完全匹配的情况

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
    // 匹配方案个数
    public static int count = 0;
    public static void kSum(List<Integer> numbers, int target) {
        //实现逻辑
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String source = sc.nextLine();
        String[] str = source.split(",");
        List<Integer> in = new ArrayList<Integer>();
        for (int i = 0; i < str.length; i++)
            in.add(Integer.parseInt(str[i]));
        int target = Integer.parseInt(sc.nextLine());
        kSum(in, target);
        System.out.println(count);
    }
}
	


可将上述代码复制到代码框,并实现kSum函数,也可以自行编码实现


输入描述:
第一行输入为可用资金金额列表,多个金额之间用逗号分隔

第二行输入为借款金额


输出描述:
满足条件的匹配方案个数,如没有满足条件的方案则输出0,相同的匹配方案可以重复计算个数
示例1

输入

8,2,1,1,1
10

输出

4

说明

相同的匹配方案可以重复计算个数
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] amount = in.nextLine().split(",");
        int target = in.nextInt();
        back(amount, target, 0);
        System.out.println(cnt);
    }
    // 回溯框架直接秒杀
    static List<Integer> select = new ArrayList<>();
    static int cnt = 0;
    public static void back(String[] amount, int target, int idx) {
        if (target < 0) return;
        if (target == 0) {
            cnt++;
            return;
        }
        for (int i = idx; i < amount.length; i++) {
            target -= Integer.parseInt(amount[i]);
            back(amount, target, i+1);
            target += Integer.parseInt(amount[i]);
        }
    }
}
发表于 2022-06-27 11:29:12 回复(0)
dfs直接求解就可以了,每一个元素都可以选择要或者不要

import java.util.*;
public class Main {
    // 匹配方案个数
    public static intcount = 0;
    public static intsum = 0;
    public static void kSum(List<Integer> numbers, int target, int i) {
        if(sum == target){
            count++;
            return;
        }
        if(i == numbers.size())  return;
        if(sum > target)  return;
        sum += numbers.get(i);
        kSum(numbers, target, i + 1);
        sum -= numbers.get(i);
        kSum(numbers, target, i + 1);
    }
   
    public static void main(String[] args) {
        Scanner sc = newScanner(System.in);
        String source = sc.nextLine();
        String[] str = source.split(",");
        List<Integer> in = newArrayList<Integer>();
        for(inti = 0; i < str.length; i++)
            in.add(Integer.parseInt(str[i]));
        inttarget = Integer.parseInt(sc.nextLine());
        kSum(in, target, 0);
        System.out.println(count);
    }
}


发表于 2020-05-26 21:28:26 回复(0)

子集和问题

发表于 2019-12-15 20:47:15 回复(0)
这题是典型的组合类型的题,用dfs求解即可,注意一下题目要求要刚好才算一个,代码如下(话说有大佬在用getline成功了吗,我不知道为什么在牛客上用getline一直报错呐,求解答~~~):
#include <bits/stdc++.h>
#include <iostream>
 
using namespace std;
 
int kSum(vector<int>& n, int loc, int target) {
    if(target == 0) return 1;
    if(target < 0) return 0;
    if(loc == n.size()) {
        return target == 0 ? 1 : 0;
    }
     
    int ans = 0;
    for(int i = loc; i < n.size(); ++i) {
        ans += kSum(n, i + 1, target - n[i]);
    }
    return ans;
}
 
int main() {
    int target;
     
    vector<int> n;
    string s;
    cin >> s;
    int temp;
    int i = 0;
    while(i < s.size()) {
        if(s[i] == ',') {
            ++i;
            continue;
        };
        int left = i;
        while(i < s.size() && s[i] != ',')
            ++i;
        temp = stoi(s.substr(left, i - left));
        ++i;
        n.push_back(temp);
    }
     
    cin >> target;
     
    cout << kSum(n, 0, target);
}


发表于 2019-12-13 16:54:23 回复(0)