传送门:hdu 5800 To My Girlfriend

题意:给定n个物品,其中i,j必选,l,m必不选,问组成体积为s的方法一共有多少种

思路:定义dp[i][j][s1][s2],表示前i种物品能够构成的体积为j,其中有s1种定为必选,s2种定为不必选;因为递推到第i层时,只与第i-1层有关,所以把第一维降到2来省内存。然后就是dp[i][j][s1][s2]=dp[i-1][j][s1][s2]+dp[i-1][j][s1][s2-1]+dp[i-1][j-a[i]][s1-1][s2]+dp[i-1][j-a[i]][s1][s2];然后就是对i,j,l,m排序了,A(2,2)*A(2,2)

/**************************************************************
    Problem:hdu 5800 To My Girlfriend
    User: youmi
    Language: C++
    Result: Accepted
    Time:1903MS
    Memory:1716K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define eps 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=4*atan(1.0);

using namespace std;
typedef long long ll;
template <class T> inline void read(T &n)
{
    char c; int flag = 1;
    for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
}
int Pow(int base, ll n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************
int n,s;
const int maxn=1000+10;
const ll mod=1000000007;
ll dp[2][maxn][3][3];
int a[maxn];
ll ans;

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        sc2(n,s);
        rep(i,1,n)
            sc(a[i]);
        zeros(dp);
        ll ans=0;
        dp[0][0][0][0]=1;
        int temp=1;
        rep(i,1,n)
        {
            zeros(dp[temp]);
            rep(j,0,s)
                rep(s1,0,2)
                    rep(s2,0,2)
                    {
                        dp[temp&1][j][s1][s2]=(dp[temp&1][j][s1][s2]+dp[temp^1][j][s1][s2])%mod;
                        if(s2>=1)
                            dp[temp&1][j][s1][s2]=(dp[temp&1][j][s1][s2]+dp[temp^1][j][s1][s2-1])%mod;
                        if(s1>=1&&j>=a[i])
                            dp[temp&1][j][s1][s2]=(dp[temp&1][j][s1][s2]+dp[temp^1][j-a[i]][s1-1][s2])%mod;
                        if(j>=a[i])
                            dp[temp&1][j][s1][s2]=(dp[temp&1][j][s1][s2]+dp[temp^1][j-a[i]][s1][s2])%mod;
                    }
            temp^=1;
        }
        temp^=1;
        rep(j,1,s)
                ans=(ans+dp[temp][j][2][2])%mod;
        ans=(ans*4)%mod;
        ptlld(ans);
    }
}

 

posted on 2016-08-06 17:04  中子星  阅读(200)  评论(0编辑  收藏  举报