题意:有一个长为n的串,每个字符是#或者.中的一个,#不超过50个
有3种覆盖串的方式:(.),(..),(.#.),分别能获得g1,g2,g3的收益,覆盖之间不能重叠
第一种方式不能使用超过K次,问能获得的最大总收益,可以不覆盖完所有n个字符
n<=1e5,0<=g1,g2,g3<=1e3
思路:显然#将串分割成了若干段,预处理出段数和每段的长度
设dp[i][j][0/1]为前i段用了j次方式一,最后一个#处有没有用方式三的最大总收益
枚举段中方式二的使用次数进行转移
可以不覆盖完n个体现在/2的下取整
理论上说应该会T,实际上只跑了63ms……
应该能用前缀最大值优化,已经跑过去了也不想写了……
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 100010 13 #define M 200010 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 29 const ll MOD=1e9+7,inv2=(MOD+1)/2; 30 double eps=1e-6; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 35 ll dp[55][N][2]; 36 int a[N]; 37 char ch[N]; 38 39 int read() 40 { 41 int v=0,f=1; 42 char c=getchar(); 43 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 44 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 45 return v*f; 46 } 47 48 int main() 49 { 50 int n=read(),K=read(); 51 ll g1,g2,g3; 52 scanf("%I64d%I64d%I64d",&g1,&g2,&g3); 53 scanf("%s",ch+1); 54 int top=1; 55 rep(i,1,n) 56 if(ch[i]=='#') top++; 57 else a[top]++; 58 while(top&&a[top]==0) top--; 59 if(top==0) 60 { 61 printf("0 "); 62 return 0; 63 } 64 memset(dp,0xcf,sizeof(dp)); 65 dp[0][0][0]=0; 66 rep(i,1,top) 67 rep(j,0,K) 68 { 69 int t=min(a[i],j); 70 rep(k,0,t) 71 { 72 if(k<=a[i]) dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-k][0]+(a[i]-k)/2*g2+k*g1); 73 if(k<=a[i]-1) dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-k][1]+(a[i]-k-1)/2*g2+g3+k*g1); 74 if(k<=a[i]-1) dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-k][0]+(a[i]-k-1)/2*g2+k*g1); 75 if(k<=a[i]-2) dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-k][1]+(a[i]-k-2)/2*g2+g3+k*g1); 76 } 77 } 78 ll ans=0; 79 rep(i,0,K) ans=max(ans,dp[top][i][0]); 80 printf("%I64d ",ans); 81 return 0; 82 }