• CodeChef:Little Elephant and Colored Coins


    类似墨墨的等式

    设f[2][j][k]表示a[i].c是否和当前颜色相同,到当前枚举到的颜色为止,颜色数为j,对mnv取模为k的最小数 

    这是个无限循环背包,用spfa优化

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<map> 
    using namespace std;
    typedef long long LL;
    const int _=1e2;
    const int maxn=30+10;
    const int maxv=2*1e5+_;
    LL inf;
    
    LL f[2][maxn][maxv];//a[i].c是否和当前颜色相同,到当前枚举到的颜色为止,颜色数为j,对mnv取模为k的最小数 
    struct SPFA
    {
        int op,j,k;
        SPFA(){} SPFA(int OP,int J,int K){op=OP,j=J,k=K;}
    }list[2*maxn*maxv];int head,tail;bool v[2][maxn][maxv];
    void spfa(int cc,int mnv,int dv)
    {
        head=1,tail=1; list[tail++]=SPFA(0,0,0);
        for(int j=1;j<=cc;j++)
            for(int k=0;k<mnv;k++)
            {
                if(f[0][j][k]!=inf)list[tail++]=SPFA(0,j,k),v[0][j][k]=true;
                if(f[1][j][k]!=inf)list[tail++]=SPFA(1,j,k),v[1][j][k]=true;
            }
        while(head!=tail)
        {
            int op=list[head].op,j=list[head].j,k=list[head].k;
            int tp=1,tj=j+1-op,tk=(k+dv)%mnv;
            if(f[tp][tj][tk]>f[op][j][k]+dv)
            {
                f[tp][tj][tk]=f[op][j][k]+dv;
                if(v[tp][tj][tk]==false)
                {
                    v[tp][tj][tk]=true;
                    list[tail]=SPFA(tp,tj,tk);
                    tail++;if(tail==2*maxn*maxv)tail=1;
                }
            }
            v[op][j][k]=false;
            head++;if(head==2*maxn*maxv)head=1;
        }
    }
        
    struct node{int v,c;}a[maxn];
    bool cmp(node n1,node n2){return n1.c<n2.c;}
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,mnv=(1<<30);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&a[i].v,&a[i].c),mnv=min(mnv,a[i].v);
        sort(a+1,a+n+1,cmp);
        
        int cc=1;
        memset(f,63,sizeof(f));inf=f[0][0][0];
        f[0][0][0]=0;
        for(int i=0;i<n;i++)//开始放第i+1种 
        {
            if(a[i+1].c!=a[i].c)
            {
                for(int j=1;j<=cc;j++)
                    for(int k=0;k<mnv;k++)
                        f[0][j][k]=min(f[0][j][k],f[1][j][k]);
            }
            spfa(cc,mnv,a[i+1].v);
            if(a[i+1].c!=a[i].c)cc++;
        }
        for(int j=1;j<=cc;j++)
            for(int k=0;k<mnv;k++)
                f[0][j][k]=min(f[0][j][k],f[1][j][k]);
            
        int Q,u;LL x;
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%lld",&x);u=x%mnv;
            bool bk=false;
            for(int i=n;i>=1;i--)
                if(f[0][i][u]<=x){printf("%d
    ",i);bk=true;break;}
            if(!bk)puts("-1");
        }
        
        return 0;
    }
  • 相关阅读:
    mybatis映射文件之获取自增的主键
    mybatis映射文件之基本的增删改查
    mybatis之全局配置文件中的标签
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.gong.mybatis.dao.EmployeeMapper.getEmpById
    mybatis之第一个mybatis程序(二)
    mybatis之第一个mybatis程序(一)
    mybatis之在eclipase中的mybatis配置文件中按下"alt+/"提示相应的标签
    springmvc之与spring进行整合
    使用 JAVA 中的动态代理实现数据库连接池
    ThreadLocal源代码分析
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10441319.html
Copyright © 2020-2023  润新知