码迷,mamicode.com
首页 > 其他好文 > 详细

计蒜客(Stone Game)01背包

时间:2020-07-10 15:07:29      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:for   多少   +=   并且   def   方案   01背包   遍历   anti   

题意:在集合中挑一些数,形成一个集合S,剩下的数形成另一个集合P,使得S>= P ,并且对于S中任意元素ai,S-ai<=P

问有多少种方案。

题目链接:https://nanti.jisuanke.com/t/41420

只要减S堆中最小的石头后满足条件,那么该取法就满足题意

设dp【k】为S堆总重量为k的方案数

把ai从大到小排序;遍历时ai就变成了最小的那块石头

所以就是01背包,取或不取这个石头;最后把满足题目条件的加到ans中

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
ll dp[150005];
int a[305];
int main()
{
    int i,j,n,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        ll sum=0;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sort(a+1,a+1+n,greater<int>());
        memset(dp,0,sizeof dp);
        dp[0]=1;
        ll ans=0;
        for(i=1;i<=n;i++){
            for(j=sum;j>=a[i];j--){
                dp[j]=(dp[j]+dp[j-a[i]])%mod;
                if(j>=sum-j&&j-a[i]<=sum-j)ans=(ans+dp[j-a[i]])%mod;
                //满足条件就把选了a【i】的方案数dp[j-a[i]]加上 而dp【j】则包含了没选a【i】的方案数,没选的前面已经加过了
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

计蒜客(Stone Game)01背包

标签:for   多少   +=   并且   def   方案   01背包   遍历   anti   

原文地址:https://www.cnblogs.com/ydw--/p/11541509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!