【Atcoder Arc060】Tak and Cards

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38083668/article/details/82750720

C - 高橋君とカード / Tak and Cards


Time limit : 2sec / Memory limit : 256MB

Score : 300 points

Problem Statement

Tak has N cards. On the i-th (1≤iN) card is written an integer xi. He is selecting one or more cards from these N cards, so that the average of the integers written on the selected cards is exactly A. In how many ways can he make his selection?

Constraints

  • 1≤N≤50
  • 1≤A≤50
  • 1≤xi≤50
  • N, A, xi are integers.

Partial Score

  • 200 points will be awarded for passing the test set satisfying 1≤N≤16.

Input

The input is given from Standard Input in the following format:

N A
x1 x2 … xN

Output

Print the number of ways to select cards such that the average of the written integers is exactly A.


Sample Input 1

Copy

4 8
7 9 8 9

Sample Output 1

Copy

5
  • The following are the 5 ways to select cards such that the average is 8:
    • Select the 3-rd card.
    • Select the 1-st and 2-nd cards.
    • Select the 1-st and 4-th cards.
    • Select the 1-st, 2-nd and 3-rd cards.
    • Select the 1-st, 3-rd and 4-th cards.

Sample Input 2

Copy

3 8
6 6 9

Sample Output 2

Copy

0

Sample Input 3

Copy

8 5
3 6 2 8 7 6 5 9

Sample Output 3

Copy

扫描二维码关注公众号,回复: 3292517 查看本文章
19

Sample Input 4

Copy

33 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3

Sample Output 4

Copy

8589934591
  • The answer may not fit into a 32-bit integer.

解析:

       平均数不太好处理,我们将问题转化一下。

       令f[i][j][k]表示处理到前i个数选了j个数和为k的方案数,可得状态转移方程:

       f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k-num[i]]

       然后就是滚动数组降掉第一维就行了,具体看代码。

代码:

#include <bits/stdc++.h>
using namespace std;

const int Max=51;
int n,m,now,num[Max],sum[Max];
long long ans;
long long f[3][Max][Max*Max];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&num[i]),sum[i]=sum[i-1]+num[i];
	f[1][0][0]=f[0][0][0]=1;
	for(int i=1;i<=n;i++)
	{
	  for(int j=1;j<=i;j++)
	    for(int k=0;k<=sum[i];k++)
	    {
	      f[now][j][k]=f[now^1][j][k];
	      if(k>=num[i]) f[now][j][k]+=f[now^1][j-1][k-num[i]];
	    }
	  now^=1;
	}
	for(int i=1;i<=n;i++) ans+=f[now^1][i][i*m];
	cout<<ans<<"\n";
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/82750720