传送门:百度之星
Problem Description
我们有 n 种不同的饮料,每种饮料有无限多瓶,第 i 种饮料一瓶提供 x[i] 毫升的水分,包含 y[i] 卡路里。
现在我们需要选择一种饮料一直喝,直到补充了至少 m 毫升的水分,我们想使得摄入的卡路里总和最小。请求出这个最小值。
一旦打开一瓶饮料,就一定要喝完。
Input
第一行一个整数 test(1≤test≤100) 表示数据组数。
对于每组数据,第一行两个整数 n,m(1≤n≤100,1≤m≤10000)。
接下来 n 行,每行两个整数 x[i], yi。
Output
对于每组数据,一行一个整数表示答案。
Sample Input
2
1 10
3 3
2 10
3 3
2 1
Sample Output
12 5
一开始以为是完全背包问题,直接求出每一种饮料最少需要多少瓶,和最少摄入的卡路里,排序,找最小值。
#include
#include
#include
using namespace std;
int w[300],c[300],f[300010];
int t,m,n;
int main()
{
scanf("%d",&t);
while(t--)
{
memset(f,0,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d%d",&w[i],&c[i]);
int k=m/w[i];
if(m-w[i]*k)
k++;
f[i]+=k*c[i];
}
sort(f+1,f+n+1);
printf("%d\n",f[1]);
}
return 0;
}
Problem Description
小沃沃一共参加了 4 门考试,每门考试满分 100 分,最低 0 分,分数是整数。
给定四门考试的总分,请问在最优情况下,四门课绩点的和最高是多少?
分数与绩点之间的对应关系如下:
95~100 4.3
90~94 4.0
85~89 3.7
80~84 3.3
75~79 3.0
70~74 2.7
67~69 2.3
65~66 2.0
62~64 1.7
60~61 1.0
0~59 0
Input
第一行一个正整数test(1≤test≤401) 表示数据组数。 接下来 test 行,每行一个正整数 x 表示四门考试的总分(0≤x≤400)。
Output
对于每组数据,一行一个数表示答案。答案保留一位小数。
Sample Input
2
0
400
Sample Output
0.0
17.2
发现可以用完全背包做。
#include
#include
#include
using namespace std;
int w[300];
double c[300],f[30010];
int t,V;
int main()
{
scanf("%d",&t);
while(t--)
{
memset(f,0,sizeof(f));
scanf("%d",&V);
w[1]=95,w[2]=90,w[3]=85,w[4]=80,w[5]=75;
w[6]=70,w[7]=67,w[8]=65,w[9]=62,w[10]=60;
c[1]=4.3,c[2]=4.0,c[3]=3.7,c[4]=3.3,c[5]=3.0;
c[6]=2.7,c[7]=2.3,c[8]=2.0,c[9]=1.7,c[10]=1.0;
for(int i=1; i<=10; i++)
for(int j=w[i]; j<=V; j++)
f[j]=max(f[j],f[j-w[i]]+c[i]);
printf("%.1lf\n",f[V]);
}
return 0;
}
Problem Description
初始有 a, b两个正整数,每次可以从中选一个大于 1 的数减 1,最后两个都会减到 1,我们想知道在过程中两个数互质的次数最多是多少。
Input
第一行一个正整数test(1≤test≤1000000) 表示数据组数。
接下来 test 行,每行两个正整数 a, b(1≤a,b≤1000)。
Output
对于每组数据,一行一个整数表示答案。
Sample Input
1
2 3
Sample Output
4
样例解释
2 3 -> 1 3 -> 1 2 -> 1 1
用了几种方法去做这个题都是TLE。后来才知道优化,先预处理,把结果记忆化到数组中,再求。
#include
#include
#include
using namespace std;
int dp[1005][1005];
int isrp(int a, int b)
{
int t;
do
{
t=a%b;
a=b;
b=t;
}
while(t!=0);
if(a==1)
return 1;
else
return 0;
}
int main()
{
int t,a,b;
scanf("%d",&t);
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=1000;j++)
{
dp[i][j]=isrp(i,j)+max(dp[i-1][j],dp[i][j-1]);
}
}
while(t--)
{
scanf("%d%d",&a,&b);
printf("%d\n",dp[a][b]);
}
return 0;
}
Problem Description
我们有一个圈,从内到外一共被分成了 nn 个环,中间是空的。
我们把从外到内第 i 层环平分成 a[i]份,其中 a[i] 是偶数,我们把这 a[i]份黑白染色,第奇数个染成黑色,第偶数个染成白色。
现在我们旋转每一层,每一层都会等概率随机到一个中止位置。
问黑色的联通块数目的期望。两块黑色的区域有交点即算联通。层之间的旋转是相互独立的。
Input
第一行一个正整数 test(1≤test≤10) 表示数据组数。
对于每组数据,第一行一个正整数 n(1≤n≤10)。
接下来一行 n 个正整数 ai,a[i]为偶数,另外保证 a 序列不降。
Output
对于每组数据,一行一个数表示答案,由于答案 A/B 中的 AB 可能很大,请输出 A/B \mod 10^ 9+7 ,假设 A/B 为最简分数,
A/B \mod 10^ 9+7 = A * B-1\mod 10^ 9+7,B-1 为满足 B-1*B \mod 10^9+7 = 1 的整数。
Sample Input
3
2
2 2
2
2 6
4
10 230 666 1000
Sample Output
1
2
500000256
样例解释
对于第一组样例,第一个环和第二个环各有一半是黑的,他们的黑色部分必然有交点,所以期望的联通块数目为 1。
对于第二组样例,旋转第一个环,只在几个特定角度上第一个环的黑色部分和第二个环的三个黑色部分都有交点,大部分情况下都只和两个黑色部分有交点,因为算期望,所以几个特定角度对答案没有影响,答案为 2。
#include
#include
#include
#define ll long long
const int p=1e9+7;
using namespace std;
int a[1005];
int t,n;
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
ll quickpow(ll m,ll n)
{
ll ans=1;
m=m%p;
while(n>0)
{
if(n&1)
ans=(ans*m)%p;
n=n>>1;
m=(m*m)%p;
}
return ans%p;
}
int main()
{
scanf("%d",&t);
while(t--)
{
int ans=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
ans+=a[i];
}
ans/=2;
for(int i=1; i<=n-1; i++)
{
int l=a[i],r=a[i+1];
int x=gcd(l,r);
l/=x;
r/=x;
x/=2;
ans-=((l+r)*quickpow(2,p-2)*x)%p;
ans=(ans%p+p)%p;
}
printf("%d\n",ans);
}
return 0;
}
其他题看缘分吧,缘分到了就会做