Codeforces Round #552 (Div. 3) E stl模拟 F dp G gcd

20 篇文章 0 订阅
13 篇文章 0 订阅

contest链接

https://codeforces.com/contest/1154

E

题解思路

直接哈希模拟删除T了,可以用 s e t set set l o w e r lower lower_ b o u n d bound bound函数减少寻找下一个没有删除元素的复杂度

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"fuck"<<endl;
#define pb  push_back
const int mod=(int)1e9+7;
const int maxn=2e5+5;
int a[maxn];
int n,k;
int pos[maxn];
set<int>s;
int fl[maxn];
signed main()
{
    IOS
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        pos[a[i]]=i;
        s.insert(i);
    }
    int now=1;
    for(int i=n;i>=1;i--)
    {
        int id=pos[i];
        if(fl[id])continue;
        fl[id]=now;
        s.erase(id);
        for(int j=1;j<=k;j++)
        {
            auto it=s.lower_bound(id);
            if(it==s.end())break;
            fl[*it]=now;
            s.erase(it);
        }
        for(int j=1;j<=k;j++)
        {
            auto it=s.lower_bound(id);
            if(it==s.begin())break;
            it--;
            fl[*it]=now;
            s.erase(it);
        }
        if(now==1)now=2;
        else now=1;
    }
    for(int i=1;i<=n;i++)
    {
        cout<<fl[i];
    }cout<<endl;


    return 0;
}

F

题解思路:

完全背包,加了一个优惠条件
在记录的时候记录相同 x x x的时候 y y y最大的
在转移的时候加一个只买一个的转移情况

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"fuck"<<endl;
#define pb  push_back
const int mod=(int)1e9+7;
const int maxn=2e5+5;
int a[maxn];
int p[2005];
int n,m,k;
int x,y;
int dp[2005];
int sum[2005];
bool cmp(int a,int b)
{
    return a>b;
}
signed main()
{
    IOS
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        //dp[i]=dp[i-1]+a[i];
    }
    sort(a+1,a+n+1);

    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        if(x<=k)
        {
            p[x]=max(p[x],y);
        }
    }

    for(int i=1;i<=k;i++)
    {
        dp[i]=dp[i-1]+a[i];
        sum[i]=sum[i-1]+a[i];
    }

    //debug
    dp[0]=0;
    for(int i=0;i<k;i++)//当前容量
    {
        dp[i+1]=min(dp[i+1],dp[i]+a[i+1]);
        for(int j=1;j<=k;j++)//枚举x
        {
            if(p[j]==0)continue;
            if(i+j<=k)
            {
                dp[i+j]=min(dp[i+j],dp[i]+sum[i+j]-sum[i+p[j]]);
            }
        }
    }
    cout<<dp[k]<<endl;



    return 0;
}

G

题解思路:

枚举gcd,找最小的两个数 a i a_{i} ai, a j a_{j} aj满足 a i a_{i} ai% g c d = = 0 gcd==0 gcd==0 a j a_{j} aj% g c d = = 0 gcd==0 gcd==0
复杂度 O ( 1 e 7 l o g ( 1 e 7 ) ) O(1e7log(1e7)) O(1e7log(1e7))


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"fuck"<<endl;
#define pb  push_back
#define endl '\n'
const int maxn=(int)1e6+5;
const int mod=(int)1e9+7;
int n;
int a[maxn];
int ma[10*maxn];
int cnt[10*maxn];
signed main()
{
    IOS
    cin>>n;
    int fir,sec;
    int res=1e18;
    int maxm=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        maxm=max(maxm,a[i]);
        if(cnt[a[i]])
        {
            if(a[i]<res)
            {
                res=a[i];
                fir=ma[a[i]];
                sec=i;
            }
        }
        else
        {
            cnt[a[i]]=1;
        }
        ma[a[i]]=i;
    }
    for(int g=1;g<=maxm;g++)//gcd
    {
        int x=-1,y=-1;
        int loax,loay;
        for(int j=g;j<=maxm;j+=g)
        {
            if(cnt[j])
            {
                if(x==-1)
                {
                    x=j;
                    loax=ma[j];
                }
                else
                {
                    y=j;
                    loay=ma[j];
                    if(res>x/g*y)
                    {
                        res=x/g*y;
                        fir=loax;
                        sec=loay;
                    }
                    break;
                }
            }
        }
    }
    cout<<min(fir,sec)<<' '<<max(fir,sec)<<endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值