题意:

给出k种属性,一个人的k种属性有初始值为,他要去打n个怪兽,第i个怪兽也有k种属性,如果当前的,这个人就可以打第i个怪兽,并且每个属性得到怪兽的加成。问你这个人最多可以打几个怪兽,并输出这个人最后的属性值。

思路:

贪心思路是要打的就打,从a小的开始打,所以先对怪兽的每种属性从小到大排序,拿k个指针去扫,对满足被打条件的属性的怪兽进行标记,当某个怪兽的所有属性都被标记了,就将b加给人,指针向后移动。

这里要用到读入挂。

代码:

int ori[10];
struct node
{
    int cost,id;
};
vector<node>v[10];
int cnt[100010];
int val[100010][10];
int pos[10];
namespace IO {
    const int MX = 4e7;
    char buf[MX]; int c, sz;
    void begin() {
        c = 0;
        sz = fread(buf, 1, MX, stdin);
    }
    inline bool read(int &t) {
        while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
        if(c >= sz) return false;
        bool flag = 0; if(buf[c] == '-') flag = 1, c++;
        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';
        if(flag) t = -t;
        return true;
    }
}
bool cmp(node x,node y)
{
    return x.cost<y.cost;
}
int main()
{
    IO::begin();
    int t,n,k,x;
    //scanf("%d",&t);
    IO::read(t);
    while(t--)
    {
        //scanf("%d%d",&n,&k);
        IO::read(n);IO::read(k);
        for(int i=1;i<=k;i++)
        {
            //scanf("%d",&ori[i]);
            IO::read(ori[i]);
            v[i].resize(n+1);
            pos[i]=0;
        }
        for(int i=1;i<=n;i++)
        {
            cnt[i]=0;
            for(int j=1;j<=k;j++)
            {
                //scanf("%d",&x);
                IO::read(x);
                v[j][i]=node{x,i};
            }
            for(int j=1;j<=k;j++)
                //scanf("%d",&val[i][j]);
                IO::read(val[i][j]);
        }
        for(int i=1;i<=k;i++)
            sort(v[i].begin()+1,v[i].begin()+n+1,cmp);
        /*for(int i=1;i<=k;i++)
        {
            for(int j=1;j<=n;j++)
                printf("(%d,%d)",v[i][j].cost,v[i][j].id);
            printf("\n");
        }*/
        int tot=0;
        while(1)
        {
            int sign=0;
            for(int i=1;i<=k;i++)
            {
                for(int j=pos[i]+1;j<=n;j++)
                {
                    if(v[i][j].cost<=ori[i])
                    {
                        sign++;
                        cnt[v[i][j].id]++;
                        if(cnt[v[i][j].id]==k)
                        {
                            tot++;
                            for(int l=1;l<=k;l++)
                                ori[l]+=val[v[i][j].id][l];
                        }
                        pos[i]=j;
                    }
                    else break;
                }
            }
            if(sign==0)break;
        }
        printf("%d\n",tot);
        for(int i=1;i<k;i++)
            printf("%d ",ori[i]);
        printf("%d\n",ori[k]);
    }
    return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

最近公共祖先 Previous
HDU6376 思维+dp Next