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 }
View Code

 

转载于:https://www.cnblogs.com/ShakuganSky/p/9459892.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CodeForces - 616D是一个关于找到一个序列中最长的第k好子段的起始位置和结束位置的问题。给定一个长度为n的序列和一个整数k,需要找到一个子段,该子段中不超过k个不同的数字。题目要求输出这个序列最长的第k好子段的起始位置和终止位置。 解决这个问题的方法有两种。第一种方法是使用尺取算法,通过维护一个滑动窗口来记录\[l,r\]中不同数的个数。每次如果这个数小于k,就将r向右移动一位;如果已经大于k,则将l向右移动一位,直到个数不大于k。每次更新完r之后,判断r-l+1是否比已有答案更优来更新答案。这种方法的时间复杂度为O(n)。 第二种方法是使用枚举r和双指针的方法。通过维护一个最小的l,满足\[l,r\]最多只有k种数。使用一个map来判断数的种类。遍历序列,如果当前数字在map中不存在,则将种类数sum加一;如果sum大于k,则将l向右移动一位,直到sum不大于k。每次更新完r之后,判断i-l+1是否大于等于y-x+1来更新答案。这种方法的时间复杂度为O(n)。 以上是两种解决CodeForces - 616D问题的方法。具体的代码实现可以参考引用\[1\]和引用\[2\]中的代码。 #### 引用[.reference_title] - *1* [CodeForces 616 D. Longest k-Good Segment(尺取)](https://blog.csdn.net/V5ZSQ/article/details/50750827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces616 D. Longest k-Good Segment(双指针+map)](https://blog.csdn.net/weixin_44178736/article/details/114328999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值