Codeforces 932E - Team Work
Problem Link:
http://codeforces.com/problemset/problem/932/E
Problem Statement:
E. Team Work
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
You have a team of N people. For a particular task, you can pick any non-empty subset of people. The cost of having x people for the task is xk.
Output the sum of costs over all non-empty subsets of people.
Input:
Only line of input contains two integers N (1 ≤ N ≤ 109) representing total number of people and k (1 ≤ k ≤ 5000).
Output:
Output the sum of costs for all non empty subsets modulo 109 + 7.
Analysis:
At the first sight, the cost of having x people for the task seems very intriguing: xk. To help make it more understandable, let us give the cost a combinatorial meaning: the ways of choosing k elements (repetitions are allowed) from a set of size x. In order to avoid duplicate counting, when we say we choose k elements from a set of size x, we must use exactly every element of the set at least once.
How do we calculate the number of ways of choosing i from j? We can either choose an element that has already appeared in choosing i - 1 from j, in which case we have j options, or choose an element that has not appeared in choosing i - 1 from j - 1, in which case we have n - j + 1 options.
Then, to calculate the sum of costs for all non empty subsets, we need to count the number of subsets in which a specific combination appears. Assume we choose k people with x distinct people used, then there are n - x people unused. These people can either belong to the set or not, so the total number of subsets from which we can obtain the current combination, i.e. a specific cost, equals the product of the number of ways of choosing k from x (as stated above) and 2n - x.
The DP Equations:
dp[i][j] = dp[i - 1][j] * j + dp[i - 1][j - 1] * (n - j + 1)
Time Complexity:
O(k2)
AC Code:
1 #include <iostream> 2 #include <sstream> 3 #include <fstream> 4 #include <string> 5 #include <vector> 6 #include <deque> 7 #include <queue> 8 #include <stack> 9 #include <set> 10 #include <map> 11 #include <algorithm> 12 #include <functional> 13 #include <utility> 14 #include <bitset> 15 #include <cmath> 16 #include <cstdlib> 17 #include <ctime> 18 #include <cstdio> 19 #include <memory.h> 20 #include <functional> 21 #include <string.h> 22 #include <iomanip> 23 #include <unordered_set> 24 #include <unordered_map> 25 using namespace std; 26 27 typedef long long ll; 28 typedef pair<int,int> pi; 29 typedef double db; 30 31 const int mod=1e9+7; 32 ll qpow(ll x,ll k){return k==0?1:1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;} 33 #define MP make_pair 34 #define FF first 35 #define SS second 36 #define LB lower_bound 37 #define UB upper_bound 38 #define PB push_back 39 #define lc ((p<<1)+1) 40 #define rc ((p<<1)+2) 41 #define rep(i,a,b) for(int i=a;i<=b;i++) 42 #define rrep(i,b,a) for(int i=b;i>=a;i--) 43 #define all(v) (v).begin(),(v).end() 44 #define clean(v,a) memset(v,a,sizeof(v)) 45 #define get(a) scanf("%d",&a) 46 #define get2(a,b) scanf("%d%d",&a,&b) 47 #define get3(a,b,c) scanf("%d%d%d",&a,&b,&c) 48 49 /* 50 * high precision: printf("%.12lf",(db)ans); 51 * 52 * clear output buffer: fflush(stdout); 53 * 54 * sync off: ios::sync_with_stdio(false); 55 * 56 */ 57 58 const int md=1e9+7; 59 const int Maxn=5005; 60 61 int n,k; 62 ll dp[Maxn][Maxn];//dp[i][j]: the ways of choosing a combination of size i with repetition among j distinct people (must choose every people at least once) 63 64 int main() 65 { 66 scanf("%d%d",&n,&k); 67 dp[0][0]=1; 68 for(int i=1;i<=k;i++) 69 { 70 for(int j=1;j<=i;j++) 71 { 72 dp[i][j]=(dp[i-1][j]*j+dp[i-1][j-1]*(n-j+1))%md; 73 } 74 } 75 ll ans=0; 76 for(int i=1;i<=min(n,k);i++) 77 { 78 ans=(ans+dp[k][i]*qpow(2,n-i))%md; 79 } 80 printf("%lld\n",ans); 81 return 0; 82 }