今年暑假不AC
之前用的是二进制枚举,超麻烦,这次的据说是贪心算法,具体还不知道是咋回事,反正对了
每个节目,结束时间越早,而且开始时间满足条件的话,那就可以理解为持续时间最短的了,按这种方法把节目排序,把所有满足条件的节目都算上的话,结果就是最多的节目个数(因为一天的时间是固定的,从早到晚,所以必定是按时间顺序看节目)
#include <bits/stdc++.h>
using namespace std;
struct jm
{
int t1,t2;
}j[101];
bool cmp(jm a,jm b)
{
return a.t2<b.t2;
}
int main()
{
int n,t,ans;
while(cin>>n&&n)
{
for(int i=1;i<=n;i++)
cin>>j[i].t1>>j[i].t2;
sort(j+1,j+1+n,cmp);
t=j[1].t2;
ans=1;
for(int i=2;i<=n;i++)
{
if(t<=j[i].t1)
{
ans++;
t=j[i].t2;
}
}
cout<<ans<<endl;
}
return 0;
}
等价交换
先按照最大兑换比例排序,然后计算即可,注意最后可能出现无法换完的情况下,具体看代码
#include <bits/stdc++.h>
using namespace std;
struct change
{
double mi,mian;
}c[1001];
bool cmp(change a,change b)
{
return a.mian/a.mi>b.mian/b.mi;
}
int main()
{
int m,n;
while(cin>>m>>n)
{
for(int i=0;i<n;i++)
cin>>c[i].mi>>c[i].mian;
sort(c,c+n,cmp);
double ans=0;
for(int i=0;i<n;i++)
{
if(m>=c[i].mi)
{
m-=c[i].mi;
ans+=c[i].mian;
}
else
{
ans+=c[i].mian*m/c[i].mi;
break;
}
}
printf("%.2lf\n",ans);
}
return 0;
}
选优秀
直接组合数乘法会变成大数乘法,需要高精度,因此利用杨辉三角和组合数性质,先打表,再直接求值,但是要注意范围
#include<bits/stdc++.h>
using namespace std;
long long m,n,f[66][66];
void excel()
{
for(long long i=0;i<=65;i++)
{
f[i][i]=1;
f[i][0]=1;
}
for(long long i=1;i<=65;i++)
{
for(long long j=1;j<i;j++)
{
f[i][j]=f[i-1][j]+f[i-1][j-1];
}
}
}
int main()
{
while(cin>>m>>n)
{
excel();
cout<<f[m][n]<<endl;
}
return 0;
}
今天学到的是:可以利用杨辉三角的性质直接求得组合数的结果,(其实也是组合数的性质之一)