SRM 533 DIV 2

  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];
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值