在考场上拿到这道题的时候,其实感觉很焯,就算看到现在也没看出这是什么题型。当时想着状态压缩dp的顺序,然后写了这个代码,结果洛谷、小图灵80pts,看别人的题解说的是记数dp+前缀和优化。最焯的是,今年ccf在官网可以通过申述成绩看到得分,就这四不像代码100pts,可谓是震惊蒟蒻一百天,求大佬看看能不能优化一下,%%%。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 1010,INF = 998244353;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<PII,PII> PPP;
#define x first
#define y second
int n,m;
char g[N][N];
int c,f;
ll C,F;
int main(){
// freopen("plant.in","r",stdin);
// freopen("plant.out","w",stdout);
int T,id;
scanf("%d%d",&T,&id);
for(int u=1;u<=T;u++){
vector<PII> q[N];
vector<PPP> state[N];
scanf("%d%d%d%d",&n,&m,&c,&f);
C=0,F=0;
for(int i=0;i<n;i++){
cin>>g[i];
}
if(c==0&&f==0){
cout<<"0 0"<<endl;
continue;
}
for(int i=0;i<m;i++){
int cnt=0;
for(int j=0;j<n;j++){
if(g[j][i]=='1'){
if(cnt>=3) q[i].push_back({j-cnt,cnt});
cnt=0;
}
else cnt++;
}
if(cnt>=3) q[i].push_back({n-cnt,cnt});
for(int l=0;l<q[i].size();l++){
PII t=q[i][l];
for(int j=t.x;j<t.x+t.y;j++){
int cnt=0;
for(int k=i;k<m;k++){
if(g[j][k]=='1'){
if(cnt>=2){
state[i].push_back({{t.x,t.y},{j,cnt-1}});
cnt=0;
}
break;
}
else cnt++;
}
if(cnt>=2){
state[i].push_back({{t.x,t.y},{j,cnt-1}});
}
}
}
if(!q[i].size()) continue;
if(state[i].size()<2) continue;
for(int j=0;j<state[i].size();j++){
for(int k=j;k<state[i].size();k++){
PPP a=state[i][j],b=state[i][k];
if(a.x.x!=b.x.x) continue;
if(b.y.x-a.y.x>=2){
if(c) C+=a.y.y*b.y.y;
if(f) F+=(a.y.y*b.y.y)*((a.x.x+a.x.y-1)-b.y.x);
}
}
}
}
C*=c,F*=f;
cout<<C%INF<<" "<<F%INF<<endl;
}
return 0;
}
谢谢大佬%%%