T 1 T_1 T1——one(3004)
Description:
一个只包含0,1的
n
⋅
m
n \cdot m
n⋅m的矩阵,可以无数次任意交换两行,求交换后最大的1的面积。
n
,
m
≤
3000
n,m\le 3000
n,m≤3000
Solution:
- 这里的操作是可以交换行,那么我们可以贪心地,找出对于每一行上的1的最大连续长度,再通过列的前缀和(后缀和)求出当前长度为 j j j的最长宽度。
Code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
template<class T>inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
const int N=3010;
int n,m;
char s[N];
bool mp[N][N];
int mx[N],cnt[N][N];
int main(){
// freopen("one.in","r",stdin);
// freopen("one.out","w",stdout);
scanf("%d%d",&n,&m);
REP(i,1,n){
scanf("%s",s+1);
REP(j,1,m) if(s[j]=='1') mp[i][j]=1;
}
REP(i,1,n) DREP(j,m,1) mx[j]=mp[i][j]?mx[j+1]+1:0,cnt[j][mx[j]]++;
int ans=0;
DREP(j,m,1) REP(i,1,m-j+1) cnt[i][j]+=cnt[i][j+1],chkmax(ans,cnt[i][j]*j);
printf("%d\n",ans);
return 0;
}
T 2 T_2 T2——calendar(3723)
Description:
有一个
n
⋅
m
n \cdot m
n⋅m的矩阵,
q
q
q次操作, 每次操作为
(
v
,
u
,
k
)
(v,u,k)
(v,u,k),将矩阵中第
(
v
+
i
,
u
−
i
+
j
)
(v+i,u-i+j)
(v+i,u−i+j)格子上的权值加上
C
j
i
C_j^i
Cji,
(
j
≥
k
,
i
∈
[
0
,
j
]
)
(j \ge k,i\in[0,j])
(j≥k,i∈[0,j])。
n
,
m
≤
300
,
q
≤
5
∗
1
0
6
n,m\le300,q\le5*10^6
n,m≤300,q≤5∗106
Solution:
- 大概就是找规律题,发现每次操作都是将做一个杨辉三角,
Code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t) for(int i=(f),i##_end_=(t);i<i##_end_;++i)
#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
#define ll long long
const int mod=998244353,N=302;
int n,m,q,x;
void Add(int &x,int y){
x+=y;
if(x>=mod)x-=mod;
}
int Rad(){
x=(1ll*100000005*x+20150823)%mod;
return x/100;
}
struct p20{
int C[N][N];
int mp[N][N];
void Init(){
C[0][0]=1;
SREP(i,1,N){
C[i][0]=C[i][i]=1;
SREP(j,1,i) Add(C[i][j]=C[i-1][j-1],C[i-1][j]);
}
}
void solve(){
Init();
while(q--){
int v=Rad()%n+1;
int u=Rad()%m+1;
int k=Rad()%(n+m-v-u+1);
REP(j,k,2*(n+m)){
if(u+v+j>n+m)break;
REP(i,0,j){
if(v+i>n)break;
if(u-i+j>m)continue;
Add(mp[v+i][u-i+j],C[j][i]);
}
}
}
REP(i,1,n) REP(j,1,m) printf("%d%c",mp[i][j]," \n"[j==m]);
}
}p1;
struct p100{
int dp[N][N][N<<1];
void solve(){
REP(i,1,q){
int u=Rad()%n+1;
int v=Rad()%m+1;
int k=Rad()%(n+m-u-v+1);
dp[u][v][k]++;
}
REP(i,1,n){
REP(j,1,m){
Add(dp[i][j][0],(dp[i][j-1][0]+dp[i-1][j][0])%mod);
REP(k,0,n+m+1) Add(dp[i][j][k],(dp[i-1][j][k+1]+dp[i][j-1][k+1])%mod);
printf("%d%c",dp[i][j][0]," \n"[j==m]);
}
}
}
}p2;
int main(){
// freopen("calendar.in","r",stdin);
// freopen("calendar.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&q,&x);
if(n<=100 && q<=100)p1.solve();
else p2.solve();
return 0;
}
T 3 T_3 T3——yummy
Description:
Solution:
Code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t) for(int i=(f),i##_end_=(t);i<i##_end_;++i)
#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
#define ll long long
template<class T>inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
template<class T>inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template<class T>inline void Rd(T &x){
x=0;char c;
while((c=getchar())<48);
do x=(x<<1)+(x<<3)+(c^48);
while((c=getchar())>47);
}
const int N=4002,M=2e4+2;
int n,p;
struct node{
int c,h,t,id;
bool operator<(const node &_)const{
return t<_.t;
}
}A[N];
int q;
struct p50{
int tot;
struct bag{
int c,w;
}mp[N];
int dp[N];
void solve(){
int D,V;
REP(i,1,q){
Rd(D),Rd(V);
tot=0;
memset(dp,0,sizeof(dp));
REP(j,1,n) if(D>=A[j].t && D<=A[j].t+p-1)mp[++tot]=(bag){A[j].c,A[j].h};
REP(j,1,tot) DREP(k,V,mp[j].c) chkmax(dp[k],dp[k-mp[j].c]+mp[j].w);
int ans=0;
REP(j,0,V) chkmax(ans,dp[j]);
printf("%d\n",ans);
}
}
}p1;
struct p100{
int dp1[N][N],dp2[N][N];
void solve(){
REP(i,1,n) A[i].id=A[i].t/p;
REP(i,1,n) {
if (A[i].id>A[i-1].id) REP(j,A[i].c,N-1) dp1[i][j]=A[i].h;
else {
memcpy(dp1[i],dp1[i-1],sizeof(dp1[i]));
DREP(j,N-1,A[i].c) chkmax(dp1[i][j],dp1[i-1][j-A[i].c]+A[i].h);
}
}
DREP(i,n,1){
if (i==n||A[i].id<A[i+1].id)REP(j,A[i].c,N-1) dp2[i][j]=A[i].h;
else {
memcpy(dp2[i],dp2[i+1],sizeof(dp2[i]));
DREP(j,N-1,A[i].c) chkmax(dp2[i][j],dp2[i+1][j-A[i].c]+A[i].h);
}
}
int D,V,l,r;
while(q--){
Rd(D),Rd(V);
l=r=0;
REP(i,1,n) if(D>=A[i].t && D<=A[i].t+p-1){
if(!l)l=i;
r=i;
}
if(A[l].id==A[r].id){
if(r<n && A[r+1].id==A[r].id)l=0;
else r=0;
}
int ans=0;
REP(j,0,V) chkmax(ans,dp1[r][j]+dp2[l][V-j]);
printf("%d\n",ans);
}
}
}p2;
int main(){
// freopen("yummy.in","r",stdin);
// freopen("yummy.out","w",stdout);
Rd(n),Rd(p);
REP(i,1,n) Rd(A[i].c),Rd(A[i].h),Rd(A[i].t);
sort(A+1,A+1+n);
Rd(q);
if(n<=50) p1.solve();
else p2.solve();
return 0;
}