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]); } }