您的位置:首页 > 其它

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这三个位.

#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];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: