zoukankan      html  css  js  c++  java
  • [JOISC2014]ストラップ

    [JOISC2014]ストラップ

    题目大意:

    (n(nle2000))个挂饰,每个挂饰有一个喜悦值(b_i(|b_i|le10^6)),下面有(b_i(b_ile10^6))个挂钩,可以用来挂别的挂饰。一开始只有一个挂钩,问喜悦值总和的最大值。

    思路:

    (f[i][j])表示考虑前(i)个挂饰,还多(j)个钩子时,喜悦值总和的最大值。

    考虑同样的一堆挂件,先挂(a_i)大的可以尽可能避免钩子不够用的情况。因此需要先将所有挂件按(a_i)从大到小排序。

    时间复杂度(mathcal O(n^2))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<climits>
    #include<algorithm>
    #include<functional>
    inline int getint() {
    	register char ch;
    	register bool neg=false;
    	while(!isdigit(ch=getchar())) neg|=ch=='-';
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return neg?-x:x;
    }
    const int N=2001;
    struct Node {
    	int a,b;
    	bool operator > (const Node &rhs) const {
    		return a>rhs.a;
    	}
    };
    Node p[N];
    int f[N][N];
    inline void upd(int &a,const int &b) {
    	a=std::max(a,b);
    }
    int main() {
    	const int n=getint();
    	for(register int i=1;i<=n;i++) {
    		p[i].a=getint();
    		p[i].b=getint();
    	}
    	std::sort(&p[1],&p[n]+1,std::greater<Node>());
    	std::fill(&f[0][0],&f[0][n]+1,INT_MIN);
    	f[0][1]=0;
    	for(register int i=1;i<=n;i++) {
    		std::copy(&f[i-1][0],&f[i-1][n]+1,f[i]);
    		for(register int j=1;j<=n;j++) {
    			if(f[i-1][j]==INT_MIN) continue;
    			upd(f[i][std::min(j-1+p[i].a,n)],f[i-1][j]+p[i].b);
    		}
    	}
    	int ans=0;
    	for(register int i=0;i<=n;i++) {
    		upd(ans,f[n][i]);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    结队完成-连续最大子数组和
    一、数据库的基础简介
    十六、Shell之expect自动化交互程
    十五、Shell之数组
    十四、循环控制
    十三、Shell之select语句
    Linux系统产生随机数的6种方法
    十二、Shell之for循环
    十一、Shell之while&&until循环
    Shell补充之后台执行脚本程序
  • 原文地址:https://www.cnblogs.com/skylee03/p/10115619.html
Copyright © 2011-2022 走看看