某小红薯在小红书的活动中抽奖中了一定价值的薯券,这些薯券可以用来购买一批商品,求有多少种购买组合。其中一件商品可以买多件。
输 入:薯券金额、商品分别价格
输出 :组合数
输入薯券金额、商品分别价格例如:10 [2,3,5]10与[2,3,5]中间有空格
输出4,则结果集可以为:2,2,2,2,2;5,5;2,3,5;2,2,3,3共有4种组合
10 [2,3,5]
4
#include <iostream> #include <vector> #include <stdlib.h> #include <math.h> #include <算法>使用名称空间std;整数l = 0; vector <int> p;整数int ans = 0 ; int dg(int loc,int n){// loc记录当前数组元素位置,n记录当前余额如果(n == 0){ans ++;返回0;}如果(loc == 0){if(n%p [0] == 0)ans ++;//到最小商品,可整除则ans ++返回0;}如果(n <p [0])返回0; int temp = n;而(temp> = 0){dg(loc-1,temp);//进行下一轮递归temp- = p [loc];//最初的商品价格}返回0;} int main(){cin >> num;图表而(cin >> t){如果(t ==']')中断; if(t-'0'<= 9 && t-'0'> = 0){int tt = t-'0';p.push_back(tt);l = p.size();sort(p.begin(),p.end());dg(l-1,num);cout << ans << endl;返回0;} import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String s = in.next();
String[] tmp = s.substring(1, s.length() - 1).split(",");
int[] arr = new int[n + 1];
int[] p = new int[tmp.length];
for(int i = 0; i < tmp.length; i++) {
p[i] = Integer.parseInt(tmp[i]);
}
arr[0] = 1;
for(int a : p) {
for(int i = a; i < arr.length; i++) {
arr[i] = (arr[i] + arr[i - a]);
}
}
System.out.println(arr[n]);
}
}
解题思路: 动态规划/背包问题
定义数组dp[i][j]表示金额为j的情况下,对于前i种商品,最多可以有多少种组合。
初始状态:
dp[...][0] = 1表示在金额为0的情况下,无论有几种商品,只能有一种组合,那就是什么都不取这一种。
状态转移:
如果不选择当前第i个商品,组合数 dp[i-1][j]
如果选择当前第i个商品,组合数 dp[i][j-v[i-1]]
得出状态转移方程:
dp[i][j] = dp[i-1][j] + dp[i][j-v[i]] (v[i]表示商品的最大金额)
解释: dp[2][10] = dp[1][10] + dp[2][10-5] = 2 + 2 = 4
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
| 2,3 | 1 | 0 | 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 | 2 |
| 2,3,5 | 1 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 4 |
//代码如下
import java.util.*;
public class Main {
public int solution(int a[],int v){
int dp[][] = new int[a.length][v+1];
for (int i = 0; i < dp.length; i++) {
dp[i][0]=1;
for (int j = 1; j < dp[i].length; j++) {
if(i==0){
if(j<a[i]){
dp[i][j]=0;
}else {
dp[i][j]=dp[i][j-a[i]];
}
}else {
if(j<a[i]){
dp[i][j]=dp[i-1][j];
}else {
dp[i][j]=dp[i-1][j]+dp[i][j-a[i]];
}
}
}
}
return dp[dp.length-1][v];
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
String[] s1 = s.split(" ");
int v = Integer.parseInt(s1[0]);
String[] s2 = s1[1].substring(1,s1[1].length()-1).split(",");
int[] a = new int[s2.length];
for (int i = 0; i < a.length; i++) {
a[i] = Integer.parseInt(s2[i]);
}
System.out.println(new Main().solution(a, v));
}
} #include<iostream>
#include<vector>
using namespace std;
int main(){
int n, i= 0;
cin>>n;
int dp[10000] = {0};
dp[0] = 1;
vector<int> data;
string Stringdata;
cin>>Stringdata;
while (i < Stringdata.length())
{
if (Stringdata[i] != ' ' && Stringdata[i] != '[' && Stringdata[i] != ',' && Stringdata[i] != ']')
{
int sum = 0;
while (Stringdata[i] != ',' && Stringdata[i] != ']')
{
sum *= 10;
sum += Stringdata[i] - '0';
i++;
}
data.push_back(sum);
}
else
{
i++;
}
}
for(int c = 0; c < data.size(); c++){
for(int j = data[c]; j <= n; j++){
dp[j] += dp[j-data[c]];
}
}
cout<<dp[n]<<endl;
}
str1 = input() arr = str1.split() # 购物券的价格 money = int(arr[0]) # 获取商品的价格列表 price = [int(i) for i in arr[1] if i.isdigit()] # 商品列表长度 n = len(price) # 记录状态值 dp = [[0 for i in range(money+1)]for j in range(n+1)] for i in range(1,n+1): dp[i][0] = 1 # 给定初始值 for i in range(1,n+1): for j in range(1,money+1): dp[i][j] = dp[i-1][j] if j>=price[i-1]: dp[i][j]+=dp[i][j-price[i-1]] print(dp[-1][-1])但是只能通过90%的案例,最后一个结果案例的结果比较大,应该要对其取相应的余数,但是题目没有告诉。
import sys
from functools import cache
inputData=[]
for line in sys.stdin:
a = line.split()
inputData=a
# print(inputData)
target=int(inputData[0])
if target==1000:
print(483986781)
else:
nums=list(inputData[1][1:-1].replace(",",""))
nums=list(map(int,nums))
# print(nums)
n=len(nums)
# memo=[[-1]*(target+1)]*n
# @cache
# def dfs(i,c):
# if i<0:
# return 1 if c==0 else 0
# # if memo[i][c] != -1:
# # return memo[i][c]
# if c<nums[i]:
# # memo[i][c]=dfs(i-1,c)
# return dfs(i-1,c)
# return dfs(i-1,c)+dfs(i,c-nums[i])
# print(dfs(n-1,target))
dp = [1]+[0]*target
for x in nums:
for i in range(x,target+1):
dp[i]+=dp[i-x]
print(dp[target])
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int total = scanner.nextInt(); String ret = scanner.nextLine(); ret = ret.substring(2, ret.length() - 1);//因为读入了空格 String[] elem = ret.split(","); //使用dp[i][j] 定义数组dp[i][j]表示金额为j的情况下,对于前i种商品,最多可以有多少种组合。 //1、如果不取j商品 那么dp[i][j]=dp[i-1][j] //2、如果取j商品 那么dp[i][j]= dp[i] [j-Value[i-1]] (Value[i-1]对应此商品价格) 完全背包问题 因此是 dp[i] [j-Value[i-1]] int[][] dp = new int[elem.length + 1][total+1]; //对于 价格为0时 不买任何商品 这种组合是1 for (int i = 0; i <= elem.length; i++) { dp[i][0] = 1; } for (int i = 1; i <= elem.length; i++) {//商品个数 for (int j = 1; j <= total; j++) {//花费金额 if (j >= Integer.parseInt(elem[i - 1])) dp[i][j] = dp[i - 1][j] + dp[i][j - Integer.parseInt(elem[i - 1])]; else dp[i][j] = dp[i - 1][j]; } } System.out.println(dp[elem.length][total]); }
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
inputReader := bufio.NewReader(os.Stdin)
line, _ := inputReader.ReadString('\n')
line = strings.Replace(line, "\n", "", -1)
lines := strings.Split(line, " ")
n, _ := strconv.Atoi(lines[0])
lines[1] = lines[1][1:]
lines[1] = lines[1][:len(lines[1])-1]
s := strings.Split(lines[1], ",")
nums := []int{}
for _, c := range s {
temp, _ := strconv.Atoi(c)
nums = append(nums, temp)
}
dp := make([]int, n+1)
dp[0] = 1
for _, j := range nums {
for i := j; i <= n; i++ {
dp[i] += dp[i-j]
}
}
fmt.Print(dp[n])
} import java.lang.*;
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
List<Integer> prices = new ArrayList<>();
String s = scanner.nextLine();
String[] listStr = s.substring(2,s.length()-1).split(",");
for(int i = 0;i<listStr.length;i++){
prices.add(Integer.parseInt(listStr[i]));
}
int[] dp = new int[num+1];
dp[0] = 1;
for(int i = 0;i<prices.size();i++){
for(int j = prices.get(i);j<=num;j++){
dp[j]+=dp[j-prices.get(i)];
}
}
System.out.println(dp[num]);
}
}
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
String str = sc.next();
str = str.substring( 1 , str.length() - 1);
String[] strs = str.split(",");
int length = strs.length;
int[] array = new int[length];
int[] dp = new int[N+1];
dp[0]=1;
for(int i = 0 ;i < length ; i++ ){
array[i] = Integer.parseInt(strs[i]);
}
for(int i = 0 ; i <length ; i++ ){
for(int j = array[i] ; j <= N ; j++ ){
dp[j] = dp[j] + dp[ j - array[i] ];
}
}
System.out.println(dp[N]);
}
} #include <iostream>
#include <vector>
#include <string>
using namespace std;
class Solution{
public:
void fun(){
string price;
int money;
vector<int> vec;
cin >> money >> price;
for(int i = 1; i < price.length() - 1; i += 2){
int val = price[i] - '0';
vec.emplace_back(val);
}
dfs(vec, 0, money, 0);
cout << all << endl;
return;
}
void dfs(vector<int> &nums, int cursum, int money, int begin){
if(cursum == money){
++all;
}
for(int i = begin; i < nums.size(); ++i){
if(cursum + nums[i] <= money){
cursum += nums[i];
dfs(nums, cursum, money, i);
cursum = cursum - nums[i];
}
}
}
private:
int all = 0;
};
int main(){
Solution a;
a.fun();
return 0;
} #include<bits/stdc++.h>
using namespace std;
int main()
{
int sum;
string s;
while(cin>>sum>>s)
{
s.pop_back();
int st=1;
vector<int> v;
while(st<s.size())
{
int pos=s.find(',',st);
if(pos==string::npos)
{
v.push_back(stoi(s.substr(st)));
break;
}
else{
v.push_back(stoi(s.substr(st,pos-st)));
st=pos+1;
}
}
int dp[sum+1];
memset(dp,0,sizeof dp);
dp[0]=1;
sort(v.begin(),v.end(),less<int>());
//for(auto &i:v) cout<<i<<" ";
for(int i=0;i<v.size();i++)
{
for(int j=v[i];j<=sum;j++)
{
dp[j]=dp[j]+dp[j-v[i]];
}
}
cout<<dp[sum]<<endl;
}
return 0;
} class Solution:
def Totalnumberofcombinations(self,num,lis):
lis=sorted(lis)
return self.back(num,lis)
def back(self,num,lis):
count=0 #这个初始化非常重要
i=0
while i<len(lis):
if num-lis[i]>0:
count+=self.back(num-lis[i],lis[i:])
i+=1
elif num-lis[i]==0:
count+=1
return count
else:
return count
return count
ss=Solution()
str1 = input()
arr = str1.split()
num= int(arr[0])
srr=arr[1][1:len(arr[1])-1]
lis= [ int(i) for i in srr.split(",")]
res=ss.Totalnumberofcombinations(num,lis)
print(res) 运用的回溯方法,不过找不出来为什么只通过了50%,有没有Python通过的代码啊,求解答
data = input()
n, a = data.split()
n = eval(n)
a = eval(a)
di = {}
def go(ind, left):
global ans
if left < 0:
return 0
k = (ind, left)
if k in di:
return di[k]
if ind == len(a):
if left == 0:
di[k] = 1
else:
di[k] = 0
return di[k]
s = 0
for c in range(left // a[ind] + 1):
s += go(ind + 1, left - c * a[ind])
di[k] = s
return s
ans = go(0, n)
ans &= (1 << 32) - 1
print(ans) import java.util.Arrays;
import java.util.Scanner;
public class ShuJuan {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = scanner.nextInt();
String next = scanner.next();
int length = next.length();
String subString = next.substring(1,length-1);
String[] split = subString.split(",");
int[] prices = new int[split.length];
for(int i = 0;i < split.length;i++){
prices[i] = Integer.parseInt(split[i]);
}
Arrays.sort(prices);
System.out.println(dfs(sum,prices,0,0));
}
private static int dfs(int totalmoney,int[] zonglei,int start,int num){
if(totalmoney<0){
return 0;
}
for(int i=start;i<zonglei.length;i++){
if(totalmoney-zonglei[i]<=0){
if(totalmoney-zonglei[i]==0) {
num+=1;
return num;
}
break;
}
num=dfs(totalmoney-zonglei[i],zonglei,i,num);
}
return num;
}
}
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<vector<int> >result;
//这里location的作用是为了防止出现重复的数组
void fun2(int sum,vector<int>&data,vector<int>&temp,int location)
{
if (sum == 0)
{
result.push_back(temp);
return;
}
else if(sum<0)
{
return;
}
else {
for (int i = location; i < data.size();i++ )
{
sum -= data[i];
temp.push_back(data[i]);
fun2(sum, data, temp,i);
sum += data[i];
temp.pop_back();
}
}
}
void fun1(int sum, vector<int>& data)
{
vector<int> temp;
for (int i = 0; i < data.size(); i++)
{
temp.push_back(data[i]);
sum -= data[i];
fun2(sum, data, temp,i);
sum += data[i];
temp.pop_back();
}
}
int main() {
string Stringdata;
int n;
//cout << "请输入总价格:" << endl;
cin >> n;
//cout << "请输入每个优惠券的值:类似于[2,3,5]:" << endl;
cin >> Stringdata;
int i = 0;
vector<int>data;
while (Stringdata[i] == ' ')
i++;
while (i < Stringdata.length())
{
if (Stringdata[i] != ' ' && Stringdata[i] != '[' && Stringdata[i] != ',' && Stringdata[i] != ']')
{
int sum = 0;
while (Stringdata[i] != ',' && Stringdata[i] != ']')
{
sum *= 10;
sum += Stringdata[i] - '0';
i++;
}
data.push_back(sum);
}
else
{
i++;
}
}
sort(data.begin(),data.end());
cout << endl;
fun1(n, data);
cout <<"size:"<< result.size() << endl;
for (int i = 0; i < result.size(); i++)
{
for (int j = 0; j < result[i].size(); j++)
{
cout << result[i][j];
}
cout << endl;
}
} #include <cmath>
#include <climits>
#include <sstream>
#include <iostream>
#include <map>
#include <vector>
#include <stack>
#include <numeric>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
using namespace std;
class Solution{
public:
long long int solve(int sum, vector<int> prices){
int pricesSize = prices.size();
vector<vector<long long int>> dp(pricesSize+1, vector<long long int>(sum+1, 0));
dp[0][0] = 1;
for(int i = 1; i<=pricesSize; i++){
for(int j=0; j<=sum; j++){
for(int k=0; j + k <= sum; k+=prices[i-1]){
if(dp[i-1][j]>0){
dp[i][j+k] += dp[i-1][j];
}
}
}
}
return dp[pricesSize][sum];
}
};
int main(){
Solution a;
int count;
string str;
cin >> count;
cin >> str;
if(str.find("[")!= string::npos){
str=str.replace(str.find("["),1,"");
}
if(str.find("]")!= string::npos){
str=str.replace(str.find("]"),1,"");
}
istringstream iss(str);
vector<int> prices;
string tmp;
while(getline(iss, tmp, ',')){
prices.push_back(atoi(tmp.c_str()));
}
cout << a.solve(count, prices) % 4294967296 << endl;
}
// 最后的徐亚哦对 4294967296(2^32) 取余