[7.11] 纪中C组

本文分享了使用高精度计算解决大数问题的方法,并通过快速排序优化字符串比较效率。此外,还探讨了一个背包问题,利用动态规划求解团队背包价值的最大化。

第一题
算个成绩而已嘛,我当时就码了一波快排然后没看数据于是你懂得。。
位数在30位以内
去你[哔——]的!这long long都装不下嘛!
于是一个古老而神秘,呸呸呸,一个久远的算法——高精度从我脑海里浮现……
然而浮现有个[哔——]用,我要打出来而且对才行
恩,唠叨的够多了
其实说白了就一个字符串(数组)快排加上高精减罢了

#include <fstream> 
#include <string>
#include <memory.h>
#include <cstdlib>
using namespace std;
string c[10001],m[10001],e[10001],x,y,z;
int n,i,sc[101],p;
void qsc(int l,int h)
{
    int i=l,j=h;
    string mid=c[(l+h)/2],t;
    if (l>=h) return;
    do
    {
        while (c[i].length()>mid.length()||c[i].length()==mid.length()&&c[i]>mid) i++;
        while (c[j].length()<mid.length()||c[j].length()==mid.length()&&c[j]<mid) j--;
        if (i<=j)
        {
            t=c[i];c[i]=c[j];c[j]=t;
            i++;j--;
        }
    }
    while (i<=j);
    qsc(i,h);
    qsc(l,j);
} 
void qsm(int l,int h)
{
    int i=l,j=h;
    string mid=m[(l+h)/2],t;
    if (l>=h) return;
    do
    {
        while (m[i].length()>mid.length()||m[i].length()==mid.length()&&m[i]>mid) i++;
        while (m[j].length()<mid.length()||m[j].length()==mid.length()&&m[j]<mid) j--;
        if (i<=j)
        {
            t=m[i];m[i]=m[j];m[j]=t;
            i++;j--;
        }
    }
    while (i<=j);
    qsm(i,h);
    qsm(l,j);
}
void qse(int l,int h)
{
    int i=l,j=h;
    string mid=e[(l+h)/2],t;
    if (l>=h) return;
    do
    {
        while (e[i].length()>mid.length()||e[i].length()==mid.length()&&e[i]>mid) i++;
        while (e[j].length()<mid.length()||e[j].length()==mid.length()&&e[j]<mid) j--;
        if (i<=j)
        {
            t=e[i];e[i]=e[j];e[j]=t;
            i++;j--;
        }
    }
    while (i<=j);
    qse(i,h);
    qse(l,j);
}
void g(string s1,string s2)
{
    int i,l,a[101],b[101];
    memset(sc,0,sizeof(sc));
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    l=s2.length();
    for (i=1;i<=l;i++)
    b[i]=s2[l-i]-'0';
    l=s1.length();
    for (i=1;i<=l;i++)
    a[i]=s1[l-i]-'0';
    for (i=1;i<=l;i++)
    {
        sc[i]=a[i]-b[i]+sc[i];
        if (sc[i]<0)
        {
            sc[i+1]=sc[i+1]-1;
            sc[i]+=10;
        }
    }
    for (i=l;i>=2;i--)
    if (sc[i]!=0)
    break;
    p=i;
}
int main()
{
    ifstream fin("score.in",ios::in);
    ofstream fout("score.out",ios::out);
    fin>>c[0]>>m[0]>>e[0];
    x=c[0];y=m[0];z=e[0];
    fin>>n;
    for (i=1;i<=n;i++)
    fin>>c[i]>>m[i]>>e[i];
    qsc(0,n);
    qsm(0,n);
    qse(0,n);
    g(c[0],x);
    for (i=p;i>=1;i--)
    fout<<sc[i];
    fout<<' ';
    g(m[0],y);
    for (i=p;i>=1;i--)
    fout<<sc[i];
    fout<<' ';
    g(e[0],z);
    for (i=p;i>=1;i--)
    fout<<sc[i];
    fout<<' ';
}

第三题
1. 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
2. 每个人都很有个性,所以每个人的背包不会完全相同。
DaA 的团队中有M 个人,那么对于整个团队,背包价值和最大是多少呢?
这道题真的很水很水个屁
很容易看得出来,就是个组合,选最大而已
然而时间复杂度不允许。。。
那我能干吗?
撸……呸,当然是码代码啊
首先DP,f[i]为价值为i时的的方案数
我不想说啦啊啊啊

#include <iostream>
#include <cstdio>
using namespace std;
int m,n;
long long s,f[25001],su,a[1000001],i,j;
int main()
{
    freopen("team.in","r",stdin);
    freopen("team.out","w",stdout);
    scanf("%d%d",&m,&n);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        su+=a[i];
    }
    f[0]=1;
    for (i=1;i<=n;i++)
    for (j=su;j>=a[i];j--)
    f[j]+=f[j-a[i]];
    for (i=su;i>=1;i--)
    if (f[i]>0)
    {
        if (f[i]>m)
        {
            s+=m*i;
            m=0;
        }
        else
        if (f[i]<=m)
        {
            s+=f[i]*i;
            m-=f[i];
        }
        if (m==0) break;
    }
    printf("%lld",s);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值