HDU 5800 To My Girlfriend 【DP】
题意
有n个物品,每个物品的重量是
其中
分析
设状态dp[i][j][x][y]为选到第i个数时,总重量为j,必选了x个和必不选y个的选法总数。则在这个状态上我们可以再选一个,成为一个必选的或不是一个必选的;也可以不选,成为一个必不选的或是不是一个必不选的。也就是说可以转移给 dp[i+1][j+a[i]][x+1][y], dp[i+1][j+a[i]][x][y], dp[i+1][j][x][y+1] 和 dp[i+1][j][x][y]
AC代码
//HDU 5800 To My Girlfriend
//AC 2017-1-19 09:55:33
//DP
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+100;
const int mod=1e9+7;
int n,s;
int a[maxn];
int dp[maxn][maxn][3][3];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&s);
for(int i=0;i<n;++i)
scanf("%d",a+i);
memset(dp,0,sizeof dp);
dp[0][0][0][0]=1;
for(int i=0;i<n;++i)
{
for(int j=0;j<=s;++j)
{
for(int x=0;x<=2;++x)
{
for(int y=0;y<=2;++y)
{
if(j+a[i]<=s)
{
if(x<2)
dp[i+1][j+a[i]][x+1][y]=(dp[i+1][j+a[i]][x+1][y]+dp[i][j][x][y])%mod;
dp[i+1][j+a[i]][x][y]=(dp[i+1][j+a[i]][x][y]+dp[i][j][x][y])%mod;
}
if(y<2)
dp[i+1][j][x][y+1]=(dp[i+1][j][x][y+1]+dp[i][j][x][y])%mod;
dp[i+1][j][x][y]=(dp[i+1][j][x][y]+dp[i][j][x][y])%mod;
}
}
}
}
long long ans=0;
for(int i=0;i<=s;++i)
ans=(ans+dp[n][i][2][2])%mod;
cout<<(ans<<2)%mod<<endl;
}
return 0;
}