非常简单的一次模拟赛 但是由于水平太菜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 }