zoukankan      html  css  js  c++  java
  • #状压dp,贪心#CF1316E Team Building

    题目

    为了组织一支排球队,你需要为队伍里的(p)个不同的位置,从(n)个人中选出(p)个人,
    且每个位置上都恰好有一个人。另外还需要从剩下的人中选出恰好(k)个人作为观众。
    对于第(i)个人,已知他作为观众时能为队伍增加(a_i)点力量,
    还有他在队伍的第(j)个位置上时能为队伍增加(s_{i,j})点力量。
    请问这只排球队力量的最大值是多少?


    分析

    由于(p)很小,考虑状压dp,
    (dp[i][s])表示前(i)个人选取为队员的状态为(s)时产生的最大力量
    为了让观众力量更大,按照贪心思想肯定要先按观众力量从大到小排序,
    还要保证选取的观众人数恰好等于(k),最后输出(dp[n][2^p-1])


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=100011; typedef long long lll;
    struct rec{int w,z[7];}a[N];
    int n,m1,m2,al,xo[N]; lll dp[128];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    bool cmp(rec x,rec y){return x.w>y.w;}
    inline void Max(lll &a,lll b){a=a>b?a:b;}
    signed main(){
    	n=iut(),m1=iut(),m2=iut(),al=1<<m1;
    	for (rr int i=1;i<al;++i) xo[i]=xo[i&(i-1)]+1;
    	for (rr int i=1;i<=n;++i) a[i].w=iut();
    	for (rr int i=1;i<=n;++i)
    	for (rr int j=0;j<m1;++j)
    	    a[i].z[j]=iut();
    	sort(a+1,a+1+n,cmp);
    	memset(dp,0xcf,sizeof(dp)),dp[0]=0;
    	for (rr int i=1;i<=n;++i)
    	for (rr int j=al-1;~j;--j){
    		if (dp[j]>=0) dp[j]+=a[i].w*(i-xo[j]<=m2);
    		for (rr int p=0;p<m1;++p) if ((j>>p)&1)
    		    Max(dp[j],dp[j^(1<<p)]+a[i].z[p]);
    	}
    	return !printf("%lld",dp[al-1]);
    }
    
  • 相关阅读:
    iPhone SDK开发基础之UIPageControl编程
    Ubuntu Linux从初学到精通
    软件架构经验总结
    CMS之图片管理(3)
    如何将简单CMS后台管理系统示例转换为Java、Php等不同后台语言的版本
    CMS之图片管理(5)
    CMS之图片管理(4)
    iphone4s中cocos2d出现闪屏,花屏的解决方案
    CMS之图片管理(1)
    5 个常用的软件质量指标
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13529415.html
Copyright © 2011-2022 走看看