zoukankan      html  css  js  c++  java
  • srm591 dv2 1000pt

    题目在这里http://community.topcoder.com/stat?c=problem_statement&pm=12750&rd=15703

    看第一队的得分S,总分是A

    如果S>A/2并且S-a[i](ai是s中最小的元素))<(A-S)+a[i],S就是可行的。(枚举最小元素?)

    先不管上面那么多。。。

    ————————————————————————————————————————————

    dp[i][s]表示用前i个数组成s的方法

    那么dp[i][s] = dp[i-1][s]+dp[i-1][s-a[i]];(这个东西好像能用背包那样倒着来。。就能去掉一维i。。)

    假设i就是这个最小元素了,那么用这个组成s有多少种方法,就知道了。。dp[i][s-a[i]](其实就是dp[s-a[i]]啦);

    如果这个s满足上面的条件呢。。就把这些方法加到结果里去。。

    ————————————————————————————————————————————

    怎么让这个i就是最小元素呢?把skills数组排一下序。。然后遍历一遍相当于枚举最小元素。。

    # include <cstdio>
    # include <iostream>
    # include <algorithm>
    # include <vector>
    # define maxn 1600000LL
    using namespace std;
    typedef long long ll;
    ll dp[maxn];
    class YetAnotherTwoTeamsProblem
    {
    public:
        long long count(vector <int> skill)
        {
            ll i,j,len = skill.size(),ans=0ll,A=0ll;
            sort(skill.begin(),skill.end());
            dp[0] = 1ll;
            for (i=0;i<len;++i)
                A += skill[i];
            cout<<A<<endl;
            for (i=len-1;i>=0;i--)
                for (j=maxn;j>=skill[i];--j)
                {
                    dp[j] = dp[j-skill[i]];
                    if (j>(A/2ll)&&(j-skill[i]<(A-j)+skill[i])) 
                        ans += dp[j];
                }
            return ans;
        }
    };
    View Code
  • 相关阅读:
    揭开正则表达式的神秘面纱
    海量数据库的查询优化及分页算法方案
    ASP.NET纯数字验证码
    ASP.NET四种页面导航方式之比较与选择
    C#数据结构之队列
    if exists
    使用tfs online做代码片段笔记管理
    强制删除数据库
    C# GetType()
    TreeView
  • 原文地址:https://www.cnblogs.com/1carus/p/3331790.html
Copyright © 2011-2022 走看看