To My Girlfriend
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 609 Accepted Submission(s): 236
Total Submission(s): 609 Accepted Submission(s): 236
Problem Description
Dear Guo
I never forget the moment I met with you.You carefully asked me: "I have a very difficult problem. Can you teach me?".I replied with a smile, "of course"."I have n items, their weight was a[i]",you said,"Let's define f(i,j,k,l,m) to be the number of the subset of the weight of n items was m in total and has No.i and No.j items without No.k and No.l items.""And then," I asked.You said:"I want to know
I never forget the moment I met with you.You carefully asked me: "I have a very difficult problem. Can you teach me?".I replied with a smile, "of course"."I have n items, their weight was a[i]",you said,"Let's define f(i,j,k,l,m) to be the number of the subset of the weight of n items was m in total and has No.i and No.j items without No.k and No.l items.""And then," I asked.You said:"I want to know
∑i=1n∑j=1n∑k=1n∑l=1n∑m=1sf(i,j,k,l,m)(i,j,k,laredifferent)
Sincerely yours,
Liao
Liao
Input
The first line of input contains an integer T
(T≤15)
indicating the number of test cases.
Each case contains 2 integers n , s (4≤n≤1000,1≤s≤1000) . The next line contains n numbers: a1,a2,…,an (1≤ai≤1000) .
Each case contains 2 integers n , s (4≤n≤1000,1≤s≤1000) . The next line contains n numbers: a1,a2,…,an (1≤ai≤1000) .
Output
Each case print the only number — the number of her would modulo
109+7
(both Liao and Guo like the number).
Sample Input
2 4 4 1 2 3 4 4 4 1 2 3 4
Sample Output
8 8
Author
UESTC
Source
2016 Multi-University Training Contest 6
这道题题意有些难理解:
给你n个数,定义f(i,j,k,l,m)为在n个数中,你选取的序列,序列满足必须包含第i,j个,不包含第l,m个元素,当然也可以包含其他的元素,这些序列的总为m,f则代表
有多少序列满足以上条件。
题目给定 s,需要我们求出m属于[0,s]的序列总数。
多校赛的时候一直想的是求出固定m值,有多少不同个数的和为m,并统计个数相同时的数目,可这毫无疑问是要n^3的时间复杂度,所以华丽丽的超时了。。。
题解出来之后,发现这就是一个背包的变形题罢了,没做出来感觉好忧伤。
题目要求等于m的序列中一定包含2个,不包含2个
定义dp[i][j][s1][s2] 代表前i个和为j的一定包含s1个,不包含s2个的序列个数。
若以a[i]代表序列
dp[i][j][s1][s2] 有4个表达式
dp[i-1][j-a[i]][s1-1][s2] 第 i 个算在一定被包含。
dp[i-1][j][s1][s2-1] 第i 个算在一定不被包含。
dp[i-1][j][s1][s2] 第i 个不在序列里,但是不计算在s1,s2中。
dp[i-1][j-a[i]][s1][s2] 第i 个在序列中,但是不计算在s1,s2中。
做的时候超内存了,所以改成滚动数组了。。。
代码:
这道题题意有些难理解:
给你n个数,定义f(i,j,k,l,m)为在n个数中,你选取的序列,序列满足必须包含第i,j个,不包含第l,m个元素,当然也可以包含其他的元素,这些序列的总为m,f则代表
有多少序列满足以上条件。
题目给定 s,需要我们求出m属于[0,s]的序列总数。
多校赛的时候一直想的是求出固定m值,有多少不同个数的和为m,并统计个数相同时的数目,可这毫无疑问是要n^3的时间复杂度,所以华丽丽的超时了。。。
题解出来之后,发现这就是一个背包的变形题罢了,没做出来感觉好忧伤。
题目要求等于m的序列中一定包含2个,不包含2个
定义dp[i][j][s1][s2] 代表前i个和为j的一定包含s1个,不包含s2个的序列个数。
若以a[i]代表序列
dp[i][j][s1][s2] 有4个表达式
dp[i-1][j-a[i]][s1-1][s2] 第 i 个算在一定被包含。
dp[i-1][j][s1][s2-1] 第i 个算在一定不被包含。
dp[i-1][j][s1][s2] 第i 个不在序列里,但是不计算在s1,s2中。
dp[i-1][j-a[i]][s1][s2] 第i 个在序列中,但是不计算在s1,s2中。
做的时候超内存了,所以改成滚动数组了。。。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1010;
int num[maxn];
typedef long long ll;
ll dp[2][maxn][3][3];
const int mod=1e9+7;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,s;
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
memset(dp,0,sizeof(dp));
dp[0][0][0][0]=1;
for(int i=1;i<=n;i++)
{
int k=i&1;
memset(dp[k],0,sizeof(dp[k]));
for(int j=0;j<=s;j++)
{
for(int s1=0;s1<=2;s1++)
for(int s2=0;s2<=2;s2++)
{
dp[k][j][s1][s2]=dp[k^1][j][s1][s2];
if(j>=num[i])
dp[k][j][s1][s2]+=dp[k^1][j-num[i]][s1][s2];
if(s1>0&&j>=num[i])
dp[k][j][s1][s2]+=dp[k^1][j-num[i]][s1-1][s2];
if(s2>0)
dp[k][j][s1][s2]+=dp[k^1][j][s1][s2-1];
dp[k][j][s1][s2]%=mod;
}
}
}
ll ans=0;
n&=1;
for(int i=0;i<=s;i++)
{
ans+=dp[n][i][2][2];
ans%=mod;
}
ans=ans*4;
ans%=mod;
printf("%I64d\n",ans);
}
return 0;
}