非常简单的一次模拟赛 但是由于水平太菜AK失败

T1 loj 507 接竹竿

题目大意:

一些纸牌 每个纸牌有花色分数 按顺序放入每个牌

放入每张牌之前 若牌中已有与这张牌花色相同的牌

可以选择将这张牌和任意一张花色相同的牌之间的所有牌全部取出,并得到与取出的所有牌点数和相同的分数

求最大得分

思路:

可以想到非常朴素的dp方程 dp i= max(dp i-1 , dp j-1 +sum j-i) (j与i同色)

设lst i 为i个颜色中 dp j-1 - sum j-1(第j张牌颜色为i)

维护这个数组即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define inf 2139062143
11 #define ll long long
12 #define MAXN 1001000
13 using namespace std;
14 inline ll read()
15 {
16     ll x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 ll n,k,s[MAXN],dp[MAXN],lst[MAXN],c[MAXN];
22 int main()
23 {
24     n=read(),k=read();
25     memset(lst,128,sizeof(lst));
26     for(ll i=1;i<=n;i++) c[i]=read();
27     for(ll i=1;i<=n;i++) s[i]=s[i-1]+read();
28     for(ll i=1;i<=n;i++)
29     {
30         dp[i]=max(dp[i-1],s[i]+lst[c[i]]);
31         lst[c[i]]=max(lst[c[i]],dp[i-1]-s[i-1]);
32     }
33     printf("%lld",dp[n]);
34 }
View Code

相关文章: