SRM 475 DIV1 900
2013-08-12 15:38
162 查看
题意:
一场考试。一些题目结果已经出来,对于j题每个人能知道自己是否做对,做对得到points[j]分,做错0分。
令一些结果还未出来的题目,对于j题知道每个人是否提交,提交了就有机会得到points[j]分,否则必然的到0分。
然后对于成绩排在前p的人中(分数相同按照id,id小的排前面),随机选择q个,问方案数。
给这DP跪,完全没思路,然后看了一眼别人的dp状态,yy乱搞,结果就过了,现在整理一下思路。
先得到每个人最多能得的分数ma[i],和最少能得到的分数mi[i],对于我们选择的q个人,我们都假设他们得到最高分,其他都得他们的最低分,这样就不会出现中间情况,总方案数也不会减少。
枚举每一个1~n,假设他是选择的q个人中得分最低的。然后DP
假设现在选择x
状态dp[i][j][k]表示前i人,有j个排名在x前面,选择了k个的方案,转移看代码。
因为每次选择的方案最后一个人都不同,所以枚举x不会出现重复。
一场考试。一些题目结果已经出来,对于j题每个人能知道自己是否做对,做对得到points[j]分,做错0分。
令一些结果还未出来的题目,对于j题知道每个人是否提交,提交了就有机会得到points[j]分,否则必然的到0分。
然后对于成绩排在前p的人中(分数相同按照id,id小的排前面),随机选择q个,问方案数。
给这DP跪,完全没思路,然后看了一眼别人的dp状态,yy乱搞,结果就过了,现在整理一下思路。
先得到每个人最多能得的分数ma[i],和最少能得到的分数mi[i],对于我们选择的q个人,我们都假设他们得到最高分,其他都得他们的最低分,这样就不会出现中间情况,总方案数也不会减少。
枚举每一个1~n,假设他是选择的q个人中得分最低的。然后DP
假设现在选择x
状态dp[i][j][k]表示前i人,有j个排名在x前面,选择了k个的方案,转移看代码。
因为每次选择的方案最后一个人都不同,所以枚举x不会出现重复。
#include <cstdio> #include <iostream> #include <cstring> #include <sstream> #include <algorithm> #include <cmath> #include <vector> #define clr(x,y) memset(x,y,sizeof(x)) using namespace std ; typedef long long ll ; const double eps = 1e-6 ; const int N = 55; int mi ,ma ; ll dp ; int n,p,q; class RabbitProgramming { public: ll solve(){ ll ans = 0; for(int x=1;x<=n;x++){ clr(dp,0); dp[0][0][0] = 1; for(int i=1;i<=n;i++){ if(i!=x){ for(int j=0;j<=n;j++){ for(int k=0;k<=n;k++){ if(i<x){ //在x的前面的分数比ma[x]小于等于,排名就在他前面了,所以和i>x分开讨论 if(mi[i] < ma[x]) dp[i][j][k] += dp[i-1][j][k]; //i不加入比x大的行列 else if(j>=1) dp[i][j][k] += dp[i-1][j-1][k]; //i必须加入比x大的行列 if(ma[i]>=ma[x]) if(j>=1&&k>=1) dp[i][j][k] += dp[i-1][j-1][k-1]; //i被选择 } else{ if(mi[i]<=ma[x]) dp[i][j][k] += dp[i-1][j][k]; else if(j>=1) dp[i][j][k] += dp[i-1][j-1][k]; if(ma[i]>ma[x]) if(j>=1&&k>=1) dp[i][j][k] += dp[i-1][j-1][k-1]; } } } } else{ for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) dp[i][j][k] = dp[i-1][j-1][k-1]; //x必须被加入 } } for(int i=0;i<=p;i++) ans += dp [i][q]; //有小于等于p个在它前面的方案都可以加入答案,而且不会出现重复, //因为对于固定了选择q个,有不同个排在前面的选择其中的方案都不会相同。 } return ans; } long long getTeams(vector <int> p, vector <string> s, int qu, int se){ ::n = s.size(); ::p = qu; ::q = se; clr(mi,0);clr(ma,0); for(int i=0;i<(int)p.size();i++){ if(p[i]>0){ for(int j=0;j<n;j++) if(s[j][i]=='Y') mi[j+1]+=p[i],ma[j+1]+=p[i]; } else{ for(int j=0;j<n;j++) if(s[j][i]=='Y') ma[j+1] += -p[i]; } } return solve(); } }; // Powered by FileEdit // Powered by TZTester 1.01 [25-Feb-2003] // Powered by CodeProcessor
相关文章推荐
- SRM 424 div1 900 ProductOfPrices 翻译
- SRM 424 div1 900 翻译
- topcoder srm 475 div1
- TopCoder SRM 612 DIV1 900
- Topcoder SRM 701 Div2 900 ThueMorseGame
- Topcoder SRM 562 DIV2 900 RandomOption
- TopCoder SRM 701 div1. 900 FibonacciStringSum - 矩阵乘法
- Topcoder SRM 618 Div2 --900
- SRM 578 Div II Level Two: GooseInZooDivTwo, DFS
- [TopCoder] SRM 586 DIV 2, 500p, 1000p, Solution
- SRM 449 DIV 1 总结(550p标记下,下次做)
- SRM 448 div1(practice)
- TopCoder SRM 474 DIV1 1000
- SRM 453 DIV1 总结
- topcoder srm 305 div1
- Topcoder SRM 497 DIV2 1000 MakeSquare
- 图论 SRM 674 Div1 250
- SRM 543 Div2
- SRM 590 DIV1
- srm 305 div2 1050(bfs中级)