背包题请拉到最后
问题 A: 不同的数字(easy)
题目描述
对于一个长度为n的数组a_1,a_2,...,a_n
你将会得到m次询问,每次询问给出l,r,你需要计算出a_l,a_(l+1),...,a_r中有多少个不同的数字
如1,2,2,3,3中有3个不同的数字,分别是1,2,3
输入
输入第一行两个整数n(1<=n<=100),代表数组长度,m(1<=m<=100),代表询问个数
第二行有n个数字,代表给定的数组.(1<=a_i<=1e6)
接下来m行,每行给出一个l,r,代表询问.(1<=l<=r<=n)
输出
对于每个询问输出一行,每行一个整数,代表区间内不同数字的个数.
样例输入
5 3
1 1 2 1 3
1 5
2 4
3 5
样例输出
3
2
3
用一个数组记录数据,每次查询可以通过桶排达成0n的时间复杂度,对于本体时间足够了(水题)
#include<bits/stdc++.h>
using namespace std;
int a[105],b[1000005];
int main()
{
int n,m;memset(b,0,sizeof(b));
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
while(m--)
{
int l,r;
cin>>l>>r;
int cnt=r-l+1;
for(int i=l;i<=r;i++)
if(b[a[i]]==1)cnt--;
else b[a[i]]=1;
cout<<cnt<<endl;
for(int i=l;i<=r;i++)
b[a[i]]=0;
}
}
问题 C: 简单的数列问题
题目描述
有这么一个数列g,g[i]=g[i-1]+i,g[1]=1
这个数列的前几项依次是 1 3 6
现在有m个询问,每个询问给出一个a,你需要判断a是否存在于这个数列中
输入
第一行给出一个m,(m<=1e5),代表询问的次数
接下来m行每行一个整数a,(a<=1e9)
输出
对于每个询问输出"YE5"或者"N0"(不含引号),当a存在于数列g中时,输出"YE5",否则输出"N0"
每次输出占一行
样例输入
6
1
2
3
4
5
6
样例输出
YE5
N0
YE5
N0
N0
YE5
数列为1+2+3。。。即n(n+1)/2。对于给定的数字乘二之后便是n(n+1)。由于对整形求根之后会省略小数,所以求根得到n。然后判定n(n+1)是否等于原数乘二即可。
还有,输出的N0和YE5。结尾分别是0和5。
#include<bits/stdc++.h>
using namespace std;
long long k;
int main()
{
int m;
scanf("%d",&m);
while(m--)
{
scanf("%lld",&k);
k<<=1;
long long t=sqrt(k);
if(t*(t+1)==k)printf("YE5\n");
else printf("N0\n");
}
}
问题 D: 盘旋矩阵
题目描述
n阶盘旋矩阵是由前n^2个自然数从最后一行第一列依次盘旋而上形成的矩阵
一个4阶盘旋矩阵如下
16 15 14 13
9 10 11 12
8 7 6 5
1 2 3 4
3*3的盘旋矩阵如下
7 8 9
6 5 4
1 2 3
现在给出一个n,你一定能够很轻松写出一个程序输出每一行的和,但是充满恶意的出题人希望你能够写出一个程序输出每一列的和
输入
输入第一行一个整数T(1<=T<=50),代表测试组数
接下来T行,每行一个数n(1<=n<=200000)
保证所有n的和<=1000000
输出
输出T行,每行n个整数,代表n阶矩阵第一列到第n列每列的和
样例输入
2
3
4
样例输出
14 15 16
34 34 34 34
女生赛原题。具体。。。第一列的数字很容易求出来。然后如果n为偶数每一列的数字都一样,奇数的话每一列加一即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long k;int t;
cin>>t;
while(t--)
{
cin>>k;
long long sum=0;
for(long long j=0;j<k;j++)
if(j&1)sum+=k*(j+1);
else sum+=k*j+1;//求出第一列
for(long long i=0;i<k;i++)
cout<<sum+(k&1?i:0)<<' ';//根据奇偶输出
cout<<endl;
}
}
问题 E: TYVJ 1005 采药
题目描述
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 如果你是辰辰,你能完成这个任务吗?
输入
输入第一行有两个整数T(1 < = T < = 1000)和M(1 < = M < = 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。
输出
输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。
样例输入
70 3
71 100
69 1
1 2
样例输出
3
提示
对于30%的数据,M < = 10;对于全部的数据,M < = 100。
裸背包。方程只需要考虑时间。
#include<bits/stdc++.h>
using namespace std;
int a[1005];
struct yao{
int c,v;
}b[105];
int main()
{
memset(a,0,sizeof(a));
int t,m;
cin>>t>>m;
for(int i=0;i<m;i++)
{
cin>>b[i].c>>b[i].v;
for(int j=t;j>=b[i].c;j--)
a[j]=max(a[j],a[j-b[i].c]+b[i].v);
}
cout<<a[t]<<endl;
}
后面那几道也是背包。哦,dp。
问题 F: TYVJ 1011 传纸条
题目描述
小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。 在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。 还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。
输入
输入文件message.in的第一行有2个用空格隔开的整数m和n,表示班里有m行n列(1< =m,n< =50)。 接下来的m行是一个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度。每行的n个整数之间用空格隔开。
输出
输出文件message.out共一行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。
样例输入
3 3
0 3 9
2 8 5
5 7 0
样例输出
34
提示
30%的数据满足:1< =m,n< =10
100%的数据满足:1< =m,n< =50
忽略文件输入输出。我突然不想讲怎么打了。。。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[55][55],b[110][55][55];
memset(b,0,sizeof(b));
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
for(int k=1;k<=n+m;k++)
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
{
int OvO=b[k-1][i-1][j-1];
OvO=max(OvO,b[k-1][i-1][j]);
OvO=max(OvO,b[k-1][i][j-1]);
OvO=max(OvO,b[k-1][i][j]);
if(i==j)b[k][i][j]=OvO+a[k-i+1][i];
else b[k][i][j]=OvO+a[k-i+1][i]+a[k-j+1][j];
}
cout<<b[n+m][m][m];
return 0;
}
问题 G: TYVJ 1013 找啊找啊找GF
题目描述
" 找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见." " 诶,别再见啊..." 七夕...七夕...七夕这个日子,对于sqybi这种单身的菜鸟来说是多么的痛苦...虽然他听着这首叫做" 找啊找啊找GF" 的歌,他还是很痛苦.为了避免这种痛苦,sqybi决定要给自己找点事情干.他去找到了七夕模拟赛的负责人zmc MM,让她给自己一个出题的任务.经过几天的死缠烂打,zmc MM终于同意了. 但是,拿到这个任务的sqybi发现,原来出题比单身更让人感到无聊-_-....所以,他决定了,要在出题的同时去办另一件能够使自己不无聊的事情--给自己找GF. sqybi现在看中了n个MM,我们不妨把她们编号1到n.请MM吃饭是要花钱的,我们假设请i号MM吃饭要花rmb[i]块大洋.而希望骗MM当自己GF是要费人品的,我们假设请第i号MM吃饭试图让她当自己GF的行为(不妨称作泡该MM)要耗费rp[i]的人品.而对于每一个MM来说,sqybi都有一个对应的搞定她的时间,对于第i个MM来说叫做time[i]. sqybi保证自己有足够的魅力用time[i]的时间搞定第i个MM^_^. sqybi希望搞到尽量多的MM当自己的GF,这点是毋庸置疑的.但他不希望为此花费太多的时间(毕竟七夕赛的题目还没出),所以他希望在保证搞到MM数量最多的情况下花费的总时间最少. sqybi现在有m块大洋,他也通过一段时间的努力攒到了r的人品(这次为模拟赛出题也攒rp哦~~).他凭借这些大洋和人品可以泡到一些MM.他想知道,自己泡到最多的MM花费的最少时间是多少. 注意sqybi在一个时刻只能去泡一个MM--如果同时泡两个或以上的MM的话,她们会打起来的...
输入
输入的第一行是n,表示sqybi看中的MM数量.接下来有n行,依次表示编号为1, 2, 3, ..., n的一个MM的信息.每行表示一个MM的信息,有三个整数:rmb, rp和time.最后一行有两个整数,分别为m和r.
输出
你只需要输出一行,其中有一个整数,表示sqybi在保证MM数量的情况下花费的最少总时间是多少.
样例输入
4
1 2 5
2 1 6
2 2 2
2 2 3
5 5
样例输出
13
提示
数据规模
对于20%数据,1< =n< =10;
对于100%数据,1< =rmb< =100,1< =rp< =100,1< =time< =1000;
对于100%数据,1< =m< =100,1< =r< =100,1< =n< =100.
Hint
sqybi说:如果题目里说的都是真的就好了...
sqybi还说,如果他没有能力泡到任何一个MM,那么他就不消耗时间了(也就是消耗的时间为0),他要用这些时间出七夕比赛的题来攒rp...
出题人
sqybi GG
显然又不是原创题。单身狗受到巨额暴击。背包。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[105],m,r,b[105],c[105],n,dfs[105][105],t[105][105];
cin>>n;
memset(dfs,0,sizeof(dfs));
memset(t,0,sizeof(t));
for(int i=0;i<n;i++)
cin>>a[i]>>b[i]>>c[i];
cin>>m>>r;
for(int i=0;i<n;i++)
for(int j=m;j>=a[i];j--)
for(int k=r;k>=b[i];k--)
{
if(dfs[j-a[i]][k-b[i]]>=dfs[j][k])
{
dfs[j][k]=dfs[j-a[i]][k-b[i]]+1;
t[j][k]=t[j-a[i]][k-b[i]]+c[i];
}
else if(dfs[j-a[i]][k-b[i]]==dfs[j][k]-1)
{
t[j][k]=min(t[j][k],c[i]+t[j-a[i]][k-b[i]]);
}
}
cout<<t[m][r];
}
问题 H: 买大米
题目描述
如果你现在有n元现金,你要用这n元现金去买大米,但市场上有m种大米,每种大米都是袋装的,其价格、重量都有可能不同,并且你只能整袋购买。你要如何才能用这有限的资购买到最多的大米呢?
输入
输入数据首先包含一个正整数T,表示有T组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示大米每袋的价格、每袋的重量以及对应种类大米的袋数。
输出
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
样例输入
1
8 2
2 100 4
4 100 2
样例输出
400
裸背包。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
int a[105];
while(t--)
{
memset(a,0,sizeof(a));
int n,m;
scanf("%d%d",&n,&m);
int r,b,q;
while(m--)
{
scanf("%d%d%d",&r,&b,&q);
for(int i=n;i>=0;i--)
for(int j=1;j<=q&&j*r<=i;j++)
{
a[i]=max(a[i],a[i-j*r]+j*b);
}
}
cout<<a[n]<<endl;
// for(int i=0;i<=8;i++)cout<<a[i]<<' ';
}
}
问题 J: the 1s
题目描述
Given any integer 0 <= n <= 10000 not divisible by 2 or 5, some multiple of n is a number which in decimal notation is a sequence of 1's. How many digits are in the smallest such a multiple of n?
输入
Each line contains a number n.
输出
Output the number of digits of the smallest multiple of n.For example,111 is the smallest multiple of 3, so when n equals 3, the result is 3
样例输入
3
7
9901
样例输出
3
6
12
不说了,引用一个博客。https://blog.csdn.net/onepiece_only/article/details/52802678
总结
突然发现我懒得讲解。。。本次题目主要为裸背包题目。背包题目主要参考就是背包九讲。这个随便一搜便有结果。什么?懒得搜索?我帮你搜索了。https://blog.csdn.net/stack_queue/article/details/53544109
懒癌触发中。。。真心不想打字。有时间再补充吧。