调了一天了把所有讨论区能看见的问题、已知的hack能改的都改了,思路也应该正确,但是#9答案永远少1
//解题思路,讨论是否满足:每组选的都带标记,是则需舍去其中价值最小的一组无法打
//然后与否取max即为答案
#include <bits/stdc++.h>
using namespace std;
const int N=210;
int dp[N][N][2];//只从前k组中选,背包容量最大为v,是1 否0 满足:每组选的都带标记
int w[N][N],c[N][N],st[N][N],pat[N],p[N][N];
//p,pat记录路径,w价值,c容量,st是否可以获得子弹
int n,m,k,aa,bb;
char z;
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>w[i][j]>>z;
if(z=='Y') st[i][j]=1;
}
}
for(int l=1;l<=m;l++){
for(int h=n;h>=1;h--){
w[h][l]+=w[h+1][l];
c[h][l]=c[h+1][l]+1-st[h][l];//容量和价值打包
}
}
for(int l=1;l<=m;l++){
for(int v=k;v>=1;v--){
dp[l][v][0]=dp[l-1][v][0];
dp[l][v][1]=dp[l-1][v][1];
for(int h=n;h>=1;h--){
if(v<c[h][l]){
break;
}
aa=dp[l-1][v-c[h][l]][0]+w[h][l];
bb=dp[l-1][v-c[h][l]][1]+w[h][l];
if(st[h][l]==0){//本点不是Y自由转移
dp[l][v][0]=max(aa,dp[l][v][0]);
dp[l][v][0]=max(bb,dp[l][v][0]);
}else{//本点为Y仅1可自由转移,0只能从0转移
if(dp[l-1][v-c[h][l]][0])dp[l][v][0]=max(aa,dp[l][v][0]);
if(bb>dp[l][v][1]){
p[l][v]=h;
dp[l][v][1]=bb;
}
}
}
}
}
int vv=k;
for(int i=m;i>=1;i--){
pat[i]=p[i][vv];//转移路径
vv-=c[pat[i]][i];
}
int res=0;
for(int i=1;i<=m;i++){
res+=c[pat[i]][i];
}
if(res<k){//判定所有端末尾都为Y需要的子弹数是否不到k,否则必然要舍去
cout<<max(dp[m][k][0],dp[m][k][1])<<endl;
return 0;
}
int kk=0x3f3f3f3f,k1=0;
for(int i=1;i<=m;i++){//舍去所有端末尾都为Y中最小的
if(pat[i]!=0){
while(st[pat[i]][i]==1){
k1+=w[pat[i]][i]-w[pat[i]+1][i]+1;
pat[i]++;
}
kk=min(k1,kk);
}
}
cout<<max(dp[m][k][0],dp[m][k][1]-kk)<<endl;
return 0;
}