zoukankan      html  css  js  c++  java
  • hdu 5800

    题意:给出一个序列(1000长度),定义f(i,j,k,l,m) 为a[i],a[j]必取,a[k],a[l]必不取和为m的子集个数。统计任一i,j,k,l,m的和是多少(i!=j!=k!=l)

    dp[i][j][k][l],表示前i个组成重量j,有k个必取l个必不取的方案数,当i+1则分四种情况,a[i+1]为必取,非必取,既不为必取也不为非必取讨论

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <math.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    using namespace std;
    typedef long long ll;
    const int N = 1000+10;
    const int mod=1e9+7;
    const double en=2.718281828459;
    using namespace std;
    int t,n,s,a[N];
    int dp[N][N][3][3];
    int main() {
     //freopen("in.txt","r",stdin);
    cin>>t;
    while(t--){
      scanf("%d%d",&n,&s);
      memset(dp,0,sizeof(dp));
      int i,j,s1,s2;
      for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
      dp[0][0][0][0]=1;
      for(i=1;i<=n;i++)
        for(j=0;j<=s;j++)
          for(s1=0;s1<=2;s1++)
            for(s2=0;s2<=2;s2++){
              dp[i][j][s1][s2]+=dp[i-1][j][s1][s2];
              dp[i][j][s1][s2]%=mod;
              if(j>=a[i]){
                dp[i][j][s1][s2]+=dp[i-1][j-a[i]][s1][s2];
                dp[i][j][s1][s2]%=mod;
              }
              if(s2>=1){
              dp[i][j][s1][s2]+=dp[i-1][j][s1][s2-1];
              dp[i][j][s1][s2]%=mod;
              }
              if(j>=a[i]&&s1>=1){
                dp[i][j][s1][s2]+=dp[i-1][j-a[i]][s1-1][s2];
                dp[i][j][s1][s2]%=mod;
              }
            }
          ll sum=0;
          for(int i=1;i<=s;i++){
            sum+=dp[n][i][2][2];
            sum%=mod;
          }
          cout<<(sum*4)%mod<<endl;
    }
    }
  • 相关阅读:
    shell:读取文件的每一行内容并输出
    shell中set命令
    shell中declare命令
    MySQL MID()函数用法
    mysql的取整函数
    二分查找算法
    zookeeper安装和使用
    Redis 集群--------Redis-cluster
    ehcahe + redis 实现多级缓存
    Redis事物
  • 原文地址:https://www.cnblogs.com/shimu/p/5743994.html
Copyright © 2011-2022 走看看