SRM 533 DIV 2
2012-02-20 00:38
323 查看
250pt. PikachuEasy.
简单的字符串判断
500pt. CasketOfStarEasy
比赛的时候我是爆搞的,简单说下dp的做法。
dp[i][j]表示从第i项到第j项所取得的最大值,状态转移方程如下:
dp[i][j]=dp[i][k]+dp[k][j]+weight[i]*weight[j]; (k>=i+1 && k<=j-1)
枚举的第k位是最后的保留位,也就是说最后保留i,k,j这三个位.
1000pt.MagicalGirl
dp[i][j]表示经过第i个女巫之后,当前的分数大小是j,所能活的最大天数
状态转移方程为
dp[i][j]=max( dp[i+1][j-(day[i+1]-day[i])] , ((1.0-win[i+1])*day[i+1]+win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]]) ;
dp[i][j]. 经过第i个女巫之后,有j分,这时要面对第i+1个女巫,有两种选择。
(1)如果不与第i+1个女巫搏斗,从day[i] 到 day[i+1],剩余的分数是 j-(day[i+1]-day[i]),这时就取决于
经过第i+1个女巫后可以存活的天数,这时dp[i][j]=dp[i+1][j-(day[i+1]-day[i])];
(2)如果与第i+1个女巫搏斗,则会有两种情况:
赢: 得到第i+1个女巫的分数gain[i+1], 则这时的总分数是 j-(day[i+1]-day[i])+gain[i+1],当然总分数要比M小,这时
这时的结果是 win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]];
输: 分数变为0,在这一天就会死掉。 结果是 (1.0-win[i+1])*day[i+1];
第二种情况综合就是 dp[i][j] = win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]] + (1.0-win[i+1])*day[i+1];
结果就是dp[0][M],第0个是虚拟的女巫,具体见代码.
简单的字符串判断
500pt. CasketOfStarEasy
比赛的时候我是爆搞的,简单说下dp的做法。
dp[i][j]表示从第i项到第j项所取得的最大值,状态转移方程如下:
dp[i][j]=dp[i][k]+dp[k][j]+weight[i]*weight[j]; (k>=i+1 && k<=j-1)
枚举的第k位是最后的保留位,也就是说最后保留i,k,j这三个位.
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <cmath> using namespace std; const int maxn = 15; int dp[maxn][maxn];//dp[i][j]表示从i到j可以取得的最大值 class CasketOfStarEasy { public: int maxEnergy(vector<int> weight) { int n=weight.size(); memset(dp,0,sizeof(dp)); for(int len=2;len<n;len++) { for(int i=0;i+len<n;i++) { for(int j=i+1;j<i+len;j++) //最后剩下第j位,第i位,第i+len位三个数 { if(dp[i][j]+dp[j][i+len]+weight[i]*weight[i+len]>dp[i][i+len]) dp[i][i+len]=dp[i][j]+dp[j][i+len]+weight[i]*weight[i+len]; } } } return dp[0][n-1]; } };
1000pt.MagicalGirl
dp[i][j]表示经过第i个女巫之后,当前的分数大小是j,所能活的最大天数
状态转移方程为
dp[i][j]=max( dp[i+1][j-(day[i+1]-day[i])] , ((1.0-win[i+1])*day[i+1]+win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]]) ;
dp[i][j]. 经过第i个女巫之后,有j分,这时要面对第i+1个女巫,有两种选择。
(1)如果不与第i+1个女巫搏斗,从day[i] 到 day[i+1],剩余的分数是 j-(day[i+1]-day[i]),这时就取决于
经过第i+1个女巫后可以存活的天数,这时dp[i][j]=dp[i+1][j-(day[i+1]-day[i])];
(2)如果与第i+1个女巫搏斗,则会有两种情况:
赢: 得到第i+1个女巫的分数gain[i+1], 则这时的总分数是 j-(day[i+1]-day[i])+gain[i+1],当然总分数要比M小,这时
这时的结果是 win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]];
输: 分数变为0,在这一天就会死掉。 结果是 (1.0-win[i+1])*day[i+1];
第二种情况综合就是 dp[i][j] = win[i+1]*dp[i+1][j-(day[i+1]-day[i])+gain[i+1]] + (1.0-win[i+1])*day[i+1];
结果就是dp[0][M],第0个是虚拟的女巫,具体见代码.
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <cmath> using namespace std; double dp[55][100005]; struct node { int day; double win; int gain; }a[55]; int cmp(node p,node q) { return p.day<q.day; } class MagicalGirl { public: double maxExpectation(int M, vector<int> day, vector<int> win, vector<int> gain) { int n=day.size(); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { a[i].day=day[i-1]; a[i].win=win[i-1]/100.0; a[i].gain=gain[i-1]; } sort(a+1,a+n+1,cmp); day[0]=0; for(int i=n;i>=0;i--) { for(int j=1;j<=M;j++) { if(i==n || j-(a[i+1].day-a[i].day)<=0) { dp[i][j] = a[i].day+j*1.0; continue; } int tmpgain = (int)min(j-(a[i+1].day-a[i].day)+a[i+1].gain,M); dp[i][j]=max(dp[i+1][j-(a[i+1].day-a[i].day)],(1.0-a[i+1].win)*a[i+1].day+a[i+1].win*(dp[i+1][tmpgain])); } } return dp[0][M]; } };
相关文章推荐
- SRM 533 DIV2
- Topcoder SRM 549 DIV2 1000 OrderOfTheHats
- [构造 哈密顿路径] SRM 704 div1 HamiltonianConstruction
- SRM 564 div1
- DP SRM 661 Div2 Hard: ColorfulLineGraphsDiv2
- SRM 638 Div2
- srm 605 div2
- TopCoder SRM 663 Div2 Problem 500 - ABBA (思维)
- TopCoder SRM 144 DIV2(200-point)
- TopCoder SRM 144 DIV 2
- topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
- topcoder srm 470 div1
- topcoder srm 700 div1 -3
- SRM 611 div2
- SRM500 DIV Ⅰ
- topcoder srm 688 div1 -3
- [DP套DP] SRM 591 div1 StringPath
- TopCoder - SRM521 div1 500 RangeSquaredSubsets
- topcoder srm 680 div1 -3
- 小朋友学TopCoder(5):SRM144 DIV1 550-point