萌新求助10分

P2704 [NOI2001] 炮兵阵地

Stars_never_set @ 2023-01-18 17:01:55

初学状压,自己想了想有思路但是只过了第一个点,大佬救救我。

$ mp_i $ 存第 $ i $ 的地图,0 表示平原,1表示山地。 $ g_i $ 存符合炮兵攻击范围的队形。 $ cnt_i $ 表示 $ i $ 的二进制的炮兵数量。 ```cpp #include<bits/stdc++.h> using namespace std; const int N=(1<<10); const int IM=2147483647; const long long LLM=9223372036854775807; inline int read() { int x=0,y=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') y=-y;c=getchar();} while(c>='0'&&c<='9'){x=x*10+(c^'0');c=getchar();} return x*y; } int n,m,num,g[N],mp[N],cnt[N],f[3][N][N]; string s; signed main() { n=read(),m=read(); for(int i=1;i<=n;i++)//初始化存地形 { cin>>s; for(int j=0;j<m;j++) { mp[i]<<=1; if(s[j]=='H') mp[i]++; } } for(int i=0;i<(1<<n);i++) { int p=i; while(p){if(p&1) cnt[i]++;p>>=1;} if((!(i&(i<<2)))&&(!(i&(i>>2)))&&(!(i&(i<<1)))&&(!(i&(i>>1)))) g[++num]=i;//存炮兵可能队形 } for(int i=1+1;i<=n+1;i++)//从第二行开始循环 { for(int l=1;l<=num;l++) { int s1=g[l]; if(s1&mp[i]) continue;//判断s1在第i行是否可行 for(int r=1;r<=num;r++) { int s2=g[r]; if((s2&mp[i-1])||(s1&s2)) continue;//判断s2在第i-1行是否可行 以及s1和s2是否冲突 for(int k=1;k<=num;k++) { int s3=g[k]; if((s3&mp[i-2])||(s1&s3)||(s2&s3)) continue;//同上 f[i%3][s1][s2]=max(f[i%3][s1][s2],f[(i-1)%3][s2][s3]+cnt[s1]);//转移 } } } } int ans=0; for(int i=1;i<=num;i++) { int s1=g[i]; for(int j=1;j<=num;j++) { int s2=g[j]; if(s1&s2) continue; ans=max(ans,f[n%3][s1][s2]); } } printf("%d\n",ans); return 0; } ```

by yi_fan0305 @ 2023-01-18 20:24:36

变量名弄混了!其次如果涉及取模,数组下标最好从零开始不然会出一些你意想不到的惊喜


by yi_fan0305 @ 2023-01-18 20:24:55

https://www.luogu.com.cn/paste/z4wl6r44


|