题目:hdu1243
方法:动态规划
思想:
本题是最长公共子序列的变种,dp[i][j]代表遇到第j个恐怖份子使用第i颗子弹的最大得分。
若in[i-1]与out[j-1]相等,即此时的子弹恰好可以用来击毙恐怖分子,因此
dp[i][j]=dp[i-1][j-1]+score[in[i-1]];//以前的最大分数+这次所得分数
否则 dp[i][j]=max(dp[i-1][j-1],max(dp[i-1][j],dp[i][j-1]));
即此时的最大得分等于 原来的最大分数dp[i-1][j-1],新增一子弹对付原来那些恐怖分子的最大得分dp[i][j-1],
用原来的子弹对付j个恐怖分子的最大得分dp[i-1][j] 三者的最大值。
代码:
#include <iostream>
using namespace std;
int dp[2005][2005];
int main(int argc, char *argv[])
{
int n,score[150];
char kind[150],in[2005],out[2005];
while(cin>>n)
{
int i,j;
for(i=0;i<n;i++)cin>>kind[i];
for(i=0;i<n;i++)
{ int tmp;cin>>tmp;
score[kind[i]]=tmp;
}
cin>>in>>out;
//memset(dp,0,sizeof(dp));
//此题不能用memset ,否则超时,
//其实也没必要清0,因为后面将会对其重新赋值
int len1=strlen(in),len2=strlen(out);
for(i=0;i<=len1;i++)dp[i][0]=0;
for(j=0;j<=len2;j++)dp[0][j]=0;
for(i=1;i<=len1;i++)
{ for(j=1;j<=len2;j++)
{ if(in[i-1]==out[j-1])dp[i][j]=dp[i-1][j-1]+score[in[i-1]];
else dp[i][j]=max(dp[i-1][j-1],max(dp[i-1][j],dp[i][j-1]));
}
}
cout<<dp[len1][len2]<<endl;
}
return 0;
}
本文介绍了一种解决HDU1243问题的方法,采用动态规划求解最长公共子序列的变种问题。核心在于计算遇到第j个目标使用第i个资源的最大收益。
227

被折叠的 条评论
为什么被折叠?



