题目描述
有一种别样“小猫钓鱼”扑克游戏。有 N 张牌,每张牌都有一个花色和点数。游戏的规则:扑克接龙时,若前面有同样花色的牌,你可以将这两张牌连同之间的牌都取走,得到的分值为取走牌点数之和。这里说的是可以,不是必须。给定扑克接龙的顺序,求最多的得分。
输入
第一行一个整数 N。
第二行 N 个整数,依次表示 1~N 张牌的花色。
第三行 N 个整数,依次表示 1~N 张牌的点数。
输出
一个整数,为游戏可以得到最大得分。
样例输入
7
1 2 1 2 3 2 3
1 4 3 4 3 4 5
样例输出
23
数据范围限制
1<=n<=3000
思路:
求游戏可以得到最大得分,闭着眼睛都想得到用动态规划来解。
f[i]表示1~i的最大得分 ;
qzh[i]表示1~i的点数和。
那么i~j区间的点数和为qzh[i]-qzh[j-1]。
第一层for枚举发f[i];
第二层枚举j~i区间点数和。
现在可推出动态转移式: f[i]=max(f[i],f[j-1]+qzh[i]-qzh[j-1]);
代码:
#include<bits/stdc++.h>
using namespace std;
int n,hs[3005],num[3005],qzh[3005],f[3005],ans;
int main(){
freopen("poker.in","r",stdin);
freopen("poker.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&hs[i]);
}
qzh[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
qzh[i]=qzh[i-1]+num[i];
}
for(int i=1;i<=n;i++){
f[i]=f[i-1];
for(int j=1;j<i;j++)
if(hs[i]==hs[j])
f[i]=max(f[i],f[j-1]+qzh[i]-qzh[j-1]);
}
printf("%d",f[n]);
fclose(stdin);
fclose(stdout);
return 0;
}
写博不易,请发现问题的大佬提出。
代码保证正确,请留赞再走。