2013 Multi-University Training Contest 1

这场比赛。。。伤心了

A - Harvest Moon(HDU4600)

题意:给你好多种种子,每种都有价格和收益。再给你一片地,问你只选一种种子播种的最大收益。

思路:枚举每种种子然后模拟。我很煞笔的开了个数组记录大小为i的土地的数量。TLE到死,最后很猥琐的除GCD,950ms水过。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define maxn 1100
#define maxm 11
#define Clear(a,b) memset(a,b,sizeof(a))
#define LL __int64

int gcd(int a,int b)       
{
    if (b == 0) return a;
    else return gcd(b,a%b);
}

inline LL Max(LL a,LL b)
{
    if (a > b) return a;
    return b;
}
inline LL Min(LL a,LL b)
{
    if (a > b) return b;
    return a;
}


short int rec[maxn][maxm] = {0};

void cal_grid(int w,int h,int g[maxm])
{
    int w3,h3;
    g[9] = (w / 3) * (h / 3);
    w3 = w % 3;
    h3 = h % 3;
    g[3 * w3 + 3 * h3 - w3 * h3]++;
    g[w3 * 3] += ((h - 3) / 3);
    g[h3 * 3] += ((w - 3) / 3);
    g[w3 * h3] += 2;
    return ;
}

LL cal_get(int day,int mon,int q,int p,int n,int m,int g[maxm])
{

    int i,j,rest,num;
    LL money = mon;
    //day--;
    //printf("day:%d\n",day);
    //for(i = 1;i <= 9;i++) printf("%d ",g[i]);printf("\n");
    //printf("%d %d %d %d",q,p,n,m);
    if (m == 0) {
        day /= n;
        n /= n;
        for(i = 0;i <= day;i++){
            if (i >= 1)
                for(j = 1;j <= 9;j++)
                    if (rec[i][j] > 0){
                    money += rec[i][j] * j * p;
                    g[j] += rec[i][j];
                    rec[i][j] = 0;
                    }
            for(j = 9;j >= 1;j--)
                if (g[j] >= 0 && i + n <= day && j * p > q){
                    num = Min(money / q,g[j]);
                    money -= num * q;
                    g[j] -= num;
                    rec[i+1][j] += num;
                    }
                }
            }
    else {
        //printf("\n%dxxx%d\n",i,day);
        int GCD = gcd(n,m);
        day /= GCD;
        n /= GCD;
        m /= GCD;
        for(i = 0;i <= day;i++){
            rest = day - i;
            for(j = 9;j >= 1;j--)
                if (rec[i][j] > 0) {
                    money += rec[i][j] * j * p;
                    if (i + m <= day) rec[i+m][j] += rec[i][j];
                    rec[i][j] = 0;
                    }
            //printf("%dxxx%d\n",i,day);
            for(j = 9;j >= 1;j--)
                if (g[j] > 0) {
                    num = Min(money / q,g[j]); //sb了
                    if (rest >= n && (((rest - n) / m) * p + p) * j > q) {
                        money -= num * q;
                        rec[i+n][j] += num;
                        g[j] -= num;
                        }
                    }
                }
            }
    //printf("OK\n");
    return money;
}

int Work()
{
    int Y,i,j,h,w,A,D,q,p,n,m;
    LL ans = 0;
    int grid[maxm] = {0},grid2[maxm] = {0};
    scanf("%d%d%d%d%d",&w,&h,&A,&D,&Y);
    cal_grid(h,w,grid);
    //for(i = 1;i <= 9;i++) printf("%d ",grid[i]);printf("\n");
    for(i = 1;i <= A;i++) {
        scanf("%d%d%d%d",&q,&p,&n,&m);
        for(j = 0;j < 10;j++)
            grid2[j] = grid[j];
        ans = Max(ans,cal_get(D,Y,q,p,n,m,grid2));
        }
    printf("%I64d\n",ans); //大傻逼
    return 0;
}

int main()
{
    int Cas;
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
    scanf("%d",&Cas);
    while(Cas--) Work();
    return 0;
}


C -  Partition(HDU 4602)

这题猥琐的算前几项然后搜的公式

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<string.h>

#define LL _int64
const LL Mod = 1000000007;

LL QPow(LL x,LL n)
{
    if (n == 0) return 1;
    if (n == 1) return x;
    LL tmp = QPow(x,n>>1);
    if (n & 1) return (((tmp * tmp) % Mod) * x) % Mod;
    else return (tmp * tmp) % Mod;
}

LL Work()
{
    LL n,k,dif;
    scanf("%I64d%I64d",&n,&k);
    dif = n - k;
    if (dif < 0) printf("0\n");
    else if (dif == 0) printf("1\n");
    else if (dif == 1) printf("2\n");
    else printf("%I64d\n",(dif+3) * QPow(2,dif-2) % Mod);
    return 0;
}

int main()
{
    int Cas;
    scanf("%d",&Cas);
    while(Cas--) Work();
    return 0;
}
F -  Magic Ball Game(HDU 4605)
题意:给你一颗树,想象一个小球从根往下落,问你小球从根到某点的概率。

思路:首先,将路径统计一下,分为左路径和右路径,然后分别统计有多少大于X的。统计我用的傻逼树。

//先分左右,离线保存,两颗傻逼树,DFS

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <ctime>
#pragma comment(linker, "/STACK:32000000")
using namespace std;

#define LL long long
#define Clear(a,b) memset(a,b,sizeof(a))

const int N = 300010;
const int INF=0x7FFFFFFF;

vector<int> O[N];
int X[N],ansx[N],ansy[N],son[N][2],w[N];

struct SBT
{
    int key,left,right,size;
} Tree_L[N],Tree_R[N];

int Root_L,Root_R,top;

void left_rot(int &x,SBT tree[])
{
    int y = tree[x].right;
    tree[x].right = tree[y].left;
    tree[y].left = x;
    tree[y].size = tree[x].size;//转上去的节点数量为先前此处节点的size
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}

void right_rot(int &x,SBT tree[])
{
    int y = tree[x].left;
    tree[x].left = tree[y].right;
    tree[y].right = x;
    tree[y].size = tree[x].size;
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}

void maintain(int &x,bool flag,SBT tree[])
{
    if(flag == false)//左边
    {
        if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)//左孩子的左子树大于右孩子
            right_rot(x,tree);
        else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size)//右孩子的右子树大于右孩子
        {
            left_rot(tree[x].left,tree);
            right_rot(x,tree);
        }
        else return;
    }
    else //右边
    {
        if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)//右孩子的右子树大于左孩子
            left_rot(x,tree);
        else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size)//右孩子的左子树大于左孩子
        {
            right_rot(tree[x].right,tree);
            left_rot(x,tree);
        }
        else return;
    }
    maintain(tree[x].left,false,tree);
    maintain(tree[x].right,true,tree);
    maintain(x,true,tree);
    maintain(x,false,tree);
}

/*
*insert没有合并相同的元素,如果出现相同的元素则把它放到右子树上,这样能保证求第k小数的时候对相同元素也能正确
*/
bool find(int &x,int key,SBT tree[])
{
    if (x == 0) return 0;
    if (key == tree[x].key) return 1;
    if (key < tree[x].key) return find(tree[x].left,key,tree);
    else return find(tree[x].right,key,tree);
}
void insert(int &x,int key,SBT tree[])
{
    if(x == 0)
    {
        x = ++top;
        tree[x].left = tree[x].right = 0;
        tree[x].size = 1;
        tree[x].key = key;
    }
    else
    {
        tree[x].size ++;
        if(key < tree[x].key) insert(tree[x].left,key,tree);
        else  insert(tree[x].right,key,tree);//相同元素插入到右子树中
        maintain(x, key >= tree[x].key,tree);//每次插入把平衡操作压入栈中
    }
}

int del(int &p,int w,SBT tree[])
{
    if (tree[p].key==w || (tree[p].left==0 && w<tree[p].key) || (tree[p].right==0 && w>tree[p].key))
    {
        int delnum=tree[p].key;
        if (tree[p].left==0 || tree[p].right==0) p=tree[p].left+tree[p].right;
        else tree[p].key=del(tree[p].left,INF,tree);
        return delnum;
    }
    if (w<tree[p].key) return del(tree[p].left,w,tree);
    else return del(tree[p].right,w,tree);
}

int remove(int &x,int key,SBT tree[])
{
    int d_key;
    //if(!x) return 0;
    tree[x].size --;
    if((key == tree[x].key)||(key < tree[x].key && tree[x].left == 0) ||
            (key>tree[x].key && tree[x].right == 0))
    {
        d_key = tree[x].key;
        if(tree[x].left && tree[x].right)
        {
            tree[x].key = remove(tree[x].left,tree[x].key+1,tree);
        }
        else
        {
            x = tree[x].left + tree[x].right;
        }
    }
    else if(key > tree[x].key)
        d_key = remove(tree[x].right,key,tree);
    else if(key < tree[x].key)
        d_key = remove(tree[x].left,key,tree);
    return d_key;
}

int getmin(int root,SBT tree[])
{
    int x;
    for(x = root ; tree[x].left; x = tree[x].left);
    return tree[x].key;
}

int getmax(int root,SBT tree[])
{
    int x;
    for(x = root ; tree[x].right; x = tree[x].right);
    return tree[x].key;
}

int select(int &x,int k,SBT tree[])//求第k小数
{
    int r = tree[tree[x].left].size + 1;
    if(r == k) return tree[x].key;
    else if(r < k) return select(tree[x].right,k - r,tree);
    else return select(tree[x].left,k,tree);
}

int rank(int &x,int key,SBT tree[])//求key排第几
{
    if(key < tree[x].key)
        return rank(tree[x].left,key,tree);
    else if(key > tree[x].key)
        return rank(tree[x].right,key,tree) + tree[tree[x].left].size + 1;
    return tree[tree[x].left].size + 1;
}

int pred(int &x,int y,int key,SBT tree[])//前驱 小于
{
    if(x == 0) return y;
    if(tree[x].key < key)
        return pred(tree[x].right,x,key,tree);
    else return pred(tree[x].left,y,key,tree);
}

int succ(int &x,int y,int key,SBT tree[])//后继 大于
{
    if(x == 0) return y;
    if(tree[x].key > key)
        return succ(tree[x].left,x,key,tree);
    else return succ(tree[x].right,y,key,tree);
}

void inorder(int &x,SBT tree[])
{
    if(x==0) return;
    else
    {
        inorder(tree[x].left,tree);
        cout<<x<<" "<<tree[x].key<<" "<<" "<<tree[x].size<<" "<<tree[tree[x].left].key<<" "<<tree[tree[x].right].key<<endl;
        inorder(tree[x].right,tree);
    }
}

//模板

void dfs(int x,int Num_L,int Num_R)
{
    //Cal
    int i,t1,t2;
    //printf("%d %d yy\n",x,O[x].size());
    for(i = 0;i < O[x].size();i++){
        int tmp = O[x][i];
        //printf("fuck\n");
        if (find(Root_L,X[tmp],Tree_L) || find(Root_R,X[tmp],Tree_R)) continue;
        //tot = Num_L + Num_R;
        //printf("fuck\n");
        insert(Root_L,X[tmp],Tree_L);
        insert(Root_R,X[tmp],Tree_R);
        t1 = rank(Root_L,X[tmp],Tree_L);
        t2 = rank(Root_R,X[tmp],Tree_R);
        remove(Root_L,X[tmp],Tree_L);
        remove(Root_R,X[tmp],Tree_R);
        t1--;t2--;
        //printf("fuck %d %d %d %d\n",t1,t2,Num_L,Num_R);
        ansx[tmp] = t2;
        ansy[tmp] = t1 * 3 + (Num_L - t1) + t2 * 3 + (Num_R - t2);
        }
    //printf("L\n");
    //L
    if (son[x][0] > 0) {
        insert(Root_L,w[x],Tree_L);
        dfs(son[x][0],Num_L+1,Num_R);
        remove(Root_L,w[x],Tree_L);
        }
    //printf("R\n");
    //R
    if (son[x][1] > 0) {
        insert(Root_R,w[x],Tree_R);
        dfs(son[x][1],Num_L,Num_R+1);
        remove(Root_R,w[x],Tree_R);
        }
    return ;
}

void Work()
{
    Root_L = Root_R = top = 0;
    int n,m,i,u,a,b;
    Clear(son,0);
    Clear(ansx,-1);
    Clear(ansy,-1);
    Clear(w,0);
    Clear(X,0);
    scanf("%d",&n);
    for(i = 1;i <= n;i++) O[i].clear();
    for(i = 1;i <= n;i++)
         scanf("%d",&w[i]);
    scanf("%d",&m);
    for(i = 1;i <= m;i++)
        scanf("%d%d%d",&u,&a,&b),
        son[u][0] = a,
        son[u][1] = b;
    scanf("%d",&m);
    for(i = 1;i <= m;i++)
        scanf("%d%d",&u,&X[i]),
        O[u].push_back(i);
    //printf("xxxx\n");
    dfs(1,0,0);
    //printf("xxxx\n");
    for(i = 1;i <= m;i++)
        if (ansx[i] == -1) printf("0\n");
        else printf("%d %d\n",ansx[i],ansy[i]);
    return ;
}

int main()
{
    int cas;
   // freopen("test.in","r",stdin);
   // freopen("test.out","w",stdout);
    scanf("%d",&cas);
    while(cas--) Work();
    return 0;
}

G - Occupy Cities(HDU 4606

  floyd+二分+最小路径覆盖


#include<iostream>
#include<string.h>
#include<stdio.h>
#include<string>
#include<math.h>

#define oo 1e9
#define eps 1e-8
#define maxn 500
#define maxm 10000

using namespace std;

struct Point
{
    int u,v;
    Point(){}
    Point(double a,double b):u(a),v(b){}

    Point operator - (const Point p) {return Point(u-p.u,v-p.v);}
}p[maxn],wall[maxn];

double ma[maxn][maxn];
int map[maxn][maxn],match[maxn],id[maxn];
bool vis[maxn];
int n,m,PP,T,N,M;

int dlcmp(double x) {return x<-eps?-1:x>eps;}
double sqr(double x) {return x*x;}

double dist(Point a,Point b) {return sqrt(sqr(a.u-b.u)+sqr(a.v-b.v));}
double cross(Point a,Point b) {return a.u*b.v-b.u*a.v;}


int segment_intersect(Point s1,Point e1,Point s2,Point e2)
{
    if (max(s1.u,e1.u)>min(s2.u,e2.u)&&max(s2.u,e2.u)>min(s1.u,e1.u)&&max(s1.v,e1.v)>min(s2.v,e2.v)&&max(s2.v,e2.v)>min(s1.v,e1.v)&&
        dlcmp(cross(e1-s1,s2-s1))*dlcmp(cross(e1-s1,e2-s1))<0&&dlcmp(cross(e2-s2,s1-s2))*dlcmp(cross(e2-s2,e1-s2))<0)
        return 1;
    else
        return 0;
}

bool NO( int x, int y )
{
    for ( int i = 1; i <= m; ++i )
    {
         if ( segment_intersect(p[x],p[y],wall[i],wall[i+m]) ) return 0;
    }
    return 1;
}

double makemap()
{
    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= N; ++j )
          if ( i != j )  ma[i][j] = oo;
          else ma[i][j] = 0;
    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j < i; ++j )
             if ( NO(i,j) )
             {
                ma[i][j] =  min(ma[i][j],dist(p[i],p[j]));
                ma[j][i] = ma[i][j];
             }
     for ( int k = 1; k <= N; ++k )
         for ( int i = 1; i <= N; ++i )
            if ( k != i )
                for ( int j = 1; j <= N; ++j )
                     if ( i !=j && k != j && ma[i][j] > ma[i][k] + ma[k][j] && ma[i][k] < oo && ma[k][j] < oo )
                         ma[i][j] = ma[i][k]+ma[k][j];
     double maxx = 0;
     for ( int i = 1; i <= n; ++i )
         for ( int j = 1; j < i; ++j )
             if ( maxx < ma[i][j] ) maxx = ma[i][j];
      return maxx;
}

int find( int x )
{
    for ( int i = 1; i <= n; ++i )
        if ( map[x][i] == 1 && vis[i] == 0 )
        {
            vis[i] = 1;
            if ( match[i] == 0 || find(match[i]) )
            {
                match[i] = x;
                return 1;
            }
        }
        return 0;
}

bool can( double mid )
{
    memset(map,0,sizeof(map));
    for ( int i = 1; i <= n; ++i )
        for ( int j = 1; j <= n; ++j )
           if ( id[i] < id[j] &&ma[i][j]-mid <=0 )
                map[i][j] = 1;
      memset(match,0,sizeof(match));
      int res = 0;
      for ( int i = 1; i <= n; ++i )
      {
          memset(vis,0,sizeof(vis));
          res += find(i);
      }
      if ( n - res <= PP ) return 1;
      else return 0;
}

int main()
{
    int u;
        scanf("%d",&T);
        while ( T-- )
        {
                scanf("%d%d%d",&n,&m,&PP);
                for ( int i = 1; i <= n; ++i )
                    scanf("%d%d",&p[i].u,&p[i].v);
                for ( int i = 1; i <= m; ++i )
                {
                     scanf("%d%d%d%d",&p[i+n].u,&p[i+n].v,&p[i+n+m].u,&p[i+n+m].v);
                     wall[i].u = p[i+n].u; wall[i].v = p[i+n].v;
                     wall[i+m].u = p[i+n+m].u;  wall[i+m].v=p[i+n+m].v;
                }
                for ( int i = 1; i <= n; ++i )
                {
                    scanf("%d",&u); id[u] = i;
                }
                N = n + m + m;
                double r = makemap(),l = 0.0,mid;
                while ( (r-l) > eps )
                {
                     mid = ( r + l ) / 2;
                     if ( can(mid) == 1  ) r = mid;
                     else l = mid;
                }
                printf("%.2lf\n",r);
        }
        return 0;
}

H - Park Visit(HDU 4607

  先用两遍DFS求出直径ans,当k小于等于直径时,答案为k-1;否则答案为(k-ans)*2+ans-1
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>

#define maxn 200000
#define maxm 500000

using namespace std;

int first[maxn],cnt,dep[maxn];
struct edd
{
    int v,next;
}e[maxm];
void add( int u, int v )
{
    e[cnt].v = v; e[cnt].next = first[u]; first[u] = cnt++;
}
void dfs(int u, int fa, int deep )
{
    dep[u] = deep;
    for ( int i = first[u]; i != -1; i = e[i].next )
    {
        int v = e[i].v;
        if ( v != fa ) dfs(v,u,deep+1);
    }
}

int main()
{
    int T,n,m,u,v;
    scanf("%d",&T);
    while ( T-- )
    {
        scanf("%d%d",&n,&m);
        memset(first,-1,sizeof(first)); cnt = 0;
        for ( int i = 1; i < n; ++i )
        {
            scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        memset(dep,0,sizeof(dep));
        int res = 1;
        dfs(res,0,0);
        for ( int i = 2; i <= n; ++i )
             if ( dep[i] > dep[res] ) res = i;
        dfs(res,0,0);
        int ans = 0,k;
        for ( int i = 1; i <= n; ++i )
            if ( ans < dep[i] ) ans = dep[i];

        ans++;
        for ( int i = 1; i <= m; ++i )
        {
            scanf("%d",&k);
            if ( k <= ans ) printf("%d\n",k-1);
            else printf("%d\n",(k-ans)*2+ans-1);
        }
    }
    return 0;
} 

K - Cards(HDU 4610

16种卡片,2^16种情况

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>

#define maxn 5000020
#define N 5000010
#define mm 50

using namespace std;

int pp[maxn+10],ge[75536];
bool Isp[maxn];
int you[mm],dan[50];
int n,m,nn,cnt,K,ans;

struct pai
{
    int x,z;
}pi[mm];

void Prim()
{
    memset(Isp,0,sizeof(Isp));
    cnt = 0;
    Isp[1] = 1;
    for ( int i = 2; i < N; ++i )
        if ( !Isp[i] )
            for ( int j = 2; j * i < N; ++j )
                Isp[i*j] = 1;
     for ( int i = 2; i < N; ++i )
         if ( !Isp[i] )
            pp[++cnt] = i;
}

bool conditions1( int x )
{
    if( !Isp[x] ) return 1;
    else return 0;
}

bool conditions2( int x )
{
    int gg =1,hh = 0;
    for ( int i = 1; pp[i] * pp[i] <= x ; ++i )
    {
        if ( x % pp[i] == 0  )
        {
            hh = 0;
            while ( x % pp[i] == 0 )
            {
                ++hh;
                x /= pp[i];
            }
            gg *= ( hh + 1 );
        }
    }
    if ( x != 1 )  gg *= 2;
    if ( !Isp[gg] ) return 1;
    else return 0;
}

bool conditions3( int x )
{
      int gg   = 1, hh = 0,nn;
      for ( int i = 1; pp[i] * pp[i] <= x; ++i )
      {
          if ( x % pp[i] == 0 )
          {
              hh = pp[i];
              nn = 1;
              while ( x % pp[i] == 0 )
              {
                   nn += hh;
                   hh *= pp[i];
                   x /= pp[i];
              }
              gg *= nn;
          }
      }
      if( x != 1 ) gg *= ( x+ 1 );
      if ( !Isp[gg] ) return 1;
      else return 0;
}

bool conditions4( int x )
{
     if( x == 1 )
        return 1;
    int yz[40], cn=-1;
    bool flag;
    for( int i = 1; pp[i] * pp[i] <= x; i++ )
    {
        if( x % pp[i] == 0 )
        {
            int nn = 0;
            while( x % pp[i] == 0 )
            {
                x /= pp[i];
                nn++;
            }
            yz[++cn] = nn;
        }
    }
    if( x != 1 ) yz[++cn] = 1;
    for( int i = 0; i <= cn; i++ )
    {
        if( yz[i] % 4 == 1 || yz[i] % 4 == 2 )
        {
            flag = 0;
            for( int j = 0; j <= cn; j++ )
            {
                if( j != i && yz[j] % 2 == 1 )
                    flag = 1;
            }
            if( flag == 0 )
                return 0;
        }
    }
    return 1;
}

int cmp( pai p1, pai p2 )
{
    return p1.z > p2.z;
}

int main()
{
    int T;
    Prim();
    for ( int i = 0; i  < 16; ++i )
    {
            pi[i].x = i;
            pi[i].z = 0;
            for ( int j = 0; j < 4; ++j )
                if ( i & (1<<j) ) pi[i].z++;
             you[i] = pi[i].z;
    }
    sort(pi,pi+16,cmp);
    scanf("%d",&T);
    while ( T-- )
    {
         scanf("%d%d",&n,&K);
         memset(ge,0,sizeof(ge));
         int now = 0,a = 0, y = 0, x = 0,z = 0;
         for  ( int i = 1; i <= n; ++i )
         {
             scanf("%d%d",&x,&z);
             a = 0;    y = 0;
             if ( conditions1(x) ) y |= 1;
             if ( conditions2(x) ) y |= 2;
             if ( conditions3(x) ) y |= 4;
             if ( conditions4(x) ) y |= 8;
             for ( int j = 0; j < 4; ++j )
                 if ( y & 1 << j ) ++a;
             if ( i == n ) printf("%d\n",a);
             else printf("%d ",a);
             ge[y] += z;
         }
         for ( int i = 0; i < 4 ; ++i )
             scanf("%d",&dan[i]);
         for ( int i = 0; i < 16; ++i )
             if ( ge[i] != 0 ) now |= 1<<i;
         ans = -1e9;
         for  ( int i = 0; i < ( 1 << 16 ); ++i )
         {
              int num = 0,res= 0, zhang = 0,gg;
              if ( i == ( i & now) )
              {
                  for ( int j = 0; j < 16; ++j )
                      if ( i & (1<<j) )
                      {   ++num; res += you[j]; zhang = zhang | j; }
                   if ( num > K ) continue;
                   for ( int j = 0; j < 16; ++j )
                        if ( i & ( 1 << pi[j].x ) )
                        {
                            gg = ge[pi[j].x];
                            --gg;
                            gg = min(gg,K-num);
                            num += gg;
                            res += you[pi[j].x] * gg;
                        }
                    if ( num != K ) continue;
                    for ( int j = 0; j <= 3 ; ++j )
                        if ( ( zhang & ( 1 << j ) )== 0 ) res += dan[j];
                    ans = max(ans,res);
                }
         }
         printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值