2020年1月22日 OJ习题【瞎写】

今年暑假不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;
}

今天学到的是:可以利用杨辉三角的性质直接求得组合数的结果,(其实也是组合数的性质之一)

发布了10 篇原创文章 · 获赞 1 · 访问量 138

猜你喜欢

转载自blog.csdn.net/shiroi2333/article/details/104069964