问题A
题目描述
给你n个钱币,去一个不找钱的商场买东西,你可以买多少种价格的物品?
输入
第一行:一个整数n,范围在[0, 100]。
第二行:n个整数,每个数范围在[1, 100]
输出
可能买的不同价格数。(包括价格0)
样例输入
3
3 2 2
样例输出
6
提示
【样例解释】:
0,2,3,4(2+2),5(2+3),7(2+2+3)
【题目分析】
要想知道刚刚好n元可以有多少种搭配,就得知道n可以由哪几个物品得来,以及购买i元的方案数…简单来说就是上一步方案数的累加。
【AC代码】
#include
using namespace std;
int n,ans;
int a[105],b[105][20005];
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
b[0][0]=1;//初始化
for(int i=1;i<=n;i++){
for(int j=0;j<10001;j++)if(b[i-1][j]!=0)b[i][j+a[i]]=1;//统计答案
//b[i][j]意思是第i个物品价值j有没有达到(我自己很难解释。。。)
for(int j=0;j<10001;j++)if(b[i-1][j]!=0)b[i][j]=1;//同上
}
for(int i=0;i<10001;i++)ans+=b[n][i];//算出最终答案
cout<<ans;
return 0;
}
【注意】别忘了初始化哦
问题B
题目描述
给你n个正整数,每个数可选或不选,问可以选一些数它们的和可以生成多少100以内的不同数?
输入
第一行:一个整数n,范围在[0, 100000]。
第二行:n个整数,每个数范围在[1, 10000]。
输出
可生成数。(包括0和100)
样例输入
3
30 50 100
样例输出
5
提示
【样例解释】:
0,30,50,80,100。
【题目分析】
要想知道可不可以生成第i个数,就得先知道第i个数由哪两个数相加得来。并累加前面的答案,即为最终答案。
【AC代码】
#include
using namespace std;
int n,ans,a;
int b[100005];
int main()
{
cin>>n;
b[0]=1;//初始化
for(int i=1;i<=n;i++)
{
cin>>a;
for(int j=100;j>=0;j--)//一维要从大到小,以免重复
if(b[j]!=0)b[j+a]=1;//判断能否到达j+a(前提是当前j是存在的,亦或者说是i为到达过的值)
}
for(int i=0;i<101;i++)ans+=b[i];//累加,算出最终答案
cout<<ans;
return 0;
}
问题C
题目描述
给你n个正整数,每个数可选或不选,要求选一些数,使它们的和为100,问有多少种方案?
输入
第一行:一个整数n,范围在[1, 100000]。
第二行:n个整数,每个数范围在[1, 10000]。
输出
方案数。(答案不超过2^63)
样例输入
6
30 50 100 70 30 40
样例输出
4
提示
【样例解释】:
30+70, 30+30+40,100,70+30。
【题目分析】
这一题与第1题有点相似,又与上一题颇为相似。只是特定了最后答案的位置,要想知道到达100的方案数,就必须知道之前的方案数,以此类推。最后的答案就在b[100]里面。
【AC代码】
#include
using namespace std;
int n,a;
int b[10005];
int main(){
cin>>n;
b[0]=1;//初始化
for(int i=1;i<=n;i++){
cin>>a;
if(a>100)continue;//判断是不是需要的数字
for(int j=200;j>=0;j--)if(b[j]!=0)b[j+a]++;//同上一题差不多,只是要;累加,统计方案数
}
cout<<b[100];//最终答案
return 0;
}
【问题D】
题目描述
给你n个正整数,每个数可选或不选,要求选一些数,使它们的和为S,输出任意一种方案。
输入
第一行:2个整数n的范围在[1, 10000],s的范围在[1, 1000000]。
第二行:n个整数,每个数范围在[1, 1000]。
输出
输出任意一种方案。如果没有方案,输出-1。
样例输入
6 110
30 50 100 70 30 40
样例输出
30 50 30
提示
样例解释:
或者 70 40也可以。
【题目分析】
这题就是更改一下上一题,记录方案以及记录路径!(重难点)然后就没什么难度了。
【AC代码】
#include
using namespace std;
long long n,a,s;
long long fa[1000005],b[1000005];
int main()
{
cin>>n>>s;
b[0]=1;//初始化
for(int i=1;i<=n;i++){
cin>>a;
if(a>s)continue;//判读是不是需要的数
for(int j=s;j>=0;j--)
{
if(b[j]!=0&&!fa[j+a])//判断这个数可不可以用以及是否可以更新路径
{
b[j+a]++;//计算方案
fa[j+a]=a;//记录路径
}
}
}
if(b[s]==0)//答案是否有解
{
cout<<-1;
return 0;
}
while(s!=0)//输出路径
{
cout<<fa[s]<<" ";
s-=fa[s];//更新下标
}
return 0;
}
问题E、F本蒟蒻还未解出,望各位大佬帮忙。
【问题E】
题目描述
给你n个整数,每个数可选或不选,要求选一些数,使它们的和为S,问有多少种方案?
输入
第一行:2个整数n和s,范围都在[1, 100]。
第二行:n个整数,每个数范围在[-100, 100]
输出
输出方案数。(答案不超过2^63)
样例输入
6 10
3 4 7 8 -1 2
样例输出
4
提示
【样例解释】:
3+7, 3+8-1, 4+7-1, 8+2
【问题F】
题目描述
给你n个正整数,要求你分成2堆,使它们各自的和尽量相同。问2堆的差距最小是多少?
输入
第一行:1个整数n,范围都在[1, 1000]。
第二行:n个整数,每个数范围在[1, 100]
输出
输出最小差距。
样例输入
7
3 4 7 8 21 27 100
样例输出
30
提示
【样例解释】:
70=3+4+7+8+21+7
30=100-70
以上就是全部了,第一次写博客,菜!