题目描述(洛谷P2240)
阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N \le 100)N(N≤100) 堆金币,第 ii 堆金币的总重量和总价值分别是 m_i,v_i(1\le m_i,v_i \le 100)mi,vi(1≤mi,vi≤100)。阿里巴巴有一个承重量为 T(T \le 1000)T(T≤1000) 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?
输入格式
第一行两个整数 N,TN,T。
接下来 NN 行,每行两个整数 m_i,v_imi,vi。
输出格式
一个实数表示答案,输出两位小数
输入输出样例
输入 #1复制
4 50 10 60 20 100 30 120 15 45
输出 #1复制
240.00
#include<stdio.h>
int main()
{
int n,m;
double value[100];
double weight[100];
double price[100];
scanf("%d %d",&n,&m);
int i,j;
double s,t,u;
double sum=0;
for(i=0;i<n;i++)
{
scanf("%lf %lf",&weight[i],&value[i]);
price[i]=value[i]/weight[i];
}
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
if(price[i]>price[j])
{
s=value[i];
value[i]=value[j];
value[j]=s;
u=weight[i];
weight[i]=weight[j];
weight[j]=u;
t=price[i];
price[i]=price[j];
price[j]=t;
}
}
}//冒泡排序,将price从大到小排序
for(i=0;i<n;i++)
{
if(weight[i]<=m)
{
sum+=value[i];
m-=weight[i];
}
else
{
sum+=price[i]*m;
break;
}
}
printf("%.2lf",sum);
return 0;
}
因为排序排大小出错了,导致我这个题目卡了好一会儿。该题目是贪心算法的一个典例。
题目描述
给定一个长度为 NN 的数列,A_1, A_2, \cdots A_NA1,A2,⋯AN,如果其中一段连续的子序列 A_i,A_i+1, \cdots A_jAi,Ai+1,⋯Aj ( i \leq ji≤j ) 之和是 KK 的倍数,我们就称这个区间 [i, j][i,j] 是 K 倍区间。
你能求出数列中总共有多少个 KK 倍区间吗?
输入描述
第一行包含两个整数 NN 和 KK( 1 \leq N,K \leq 10^51≤N,K≤105 )。
以下 N 行每行包含一个整数 A_iAi ( 1 \leq A_i \leq 10^51≤Ai≤105 )
输出描述
输出一个整数,代表 K 倍区间的数目。
输入输出样例
示例
输入
5 2
1
2
3
4
5
输出
6
运行限制
- 最大运行时间:2s
- 最大运行内存: 256M
#include<stdio.h>
int main()
{
long long int n,k;
long long int i,j;
long long int a[100];
scanf("%lld %lld",&n,&k);
long long int sum;
long long int count;
for(i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
for(i=0;i<n;i++)
{
for(j=i+1;j<=n;j++)
{
sum+=a[j-1];
if(sum%k==0)
{
count++;
}
}
sum=0;
}
printf("%lld",count);
return 0;
}
这个是按照我自己的思路写的代码(不能通过,时间复杂度是O(n^2)运行超时了)
在其他人ac的文章里面看到了前缀和、取模的方法来解决这个问题(我还没能理解的下来,下次再做一次)