2020 年百度之星·程序设计大赛 - 初赛一
[toc]
6743 Drink
题解:
每一种饮料求一个卡路里,取最小值
第一看以为是背包,其实出题人在第二层
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int dp[10005];
inline int read() {
char ch = getchar();
int x = 0, f = 1;
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
} while('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
} return x * f;
}
int main()
{
int t,e,f,m,n,pi,wi;
t=read();
while(t--)
{
scanf("%d%d",&n,&m);
//m=read();
int sum=10000;
for(int i=1;i<=n;i++)
{
wi=read();
pi=read();
int a;
if(m%wi==0)a=m/wi;
else a=m/wi+1;
sum=min(a*pi,sum);
}
printf("%d\n",sum);
//cout<<dp[m]<<endl;
}
return 0;
}
6744 GPA
题解:
给的一个分数范围,我们要让分数总和最高,就要找怎么给四个成绩赋分最有价值。一个分数区间对应的绩点是一样的,那我们就取分数区间的最低分即可,[95,100]都对应4.3,那我们就取95就行
具体做法我是这样的,用一个数组来村每个区间的最小数,用另一数组来存每个区间最小数对应的绩点,然后四个for循环暴力完事
代码:
#include<iostream>
#include<cstdio>
using namespace std;
double a[104];
int b[]={
0,0,60,62,65,67,70,75,80,85,90,95};
void init()
{
a[0]=0;a[60]=1.0;a[62]=1.7;a[65]=2.0;a[67]=2.3;a[70]=2.7;a[75]=3.0;
a[80]=3.3;a[85]=3.7;a[90]=4.0;a[95]=4.3;
}
int main()
{
int t;
init();
scanf("%d",&t);
while(t--)
{
double sum=0;
int x;
scanf("%d",&x);
for(int i=1;i<=11;i++)
{
for(int j=1;j<=11;j++)
{
for(int k=1;k<=11;k++)
{
for(int w=1;w<=11;w++)
{
if(b[i]+b[j]+b[k]+b[w]<=x)
{
double ans=a[b[i]]+a[b[j]]+a[b[k]]+a[b[w]];
if(ans>sum)sum=ans;
}
}
}
}
}
printf("%.1f\n",sum);
}
}
6745 Dec
题解:
对于a和b,a和b的答案一定是在a-1,b或者a,b-1的基础上来的,如果a和b本身是互质则在前面的基础上+1,否则不加。
所以dp递推就行
看看数据,所以dp要预处理,然后直接输出答案
代码:
#include<iostream>
#include<cstdio>
#include <bitset>
using namespace std;
bitset<10000010> g;
int n,m,x,dp[1004][1005],top=0;
int gcd(int a,int b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=1002;i++)
for(int j=1;j<=1002;j++)
{
if(dp[i][j])continue;
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(gcd(i,j)==1)dp[i][j]++;
}
while(t--)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",dp[a][b]);
}
}