题解:P10267 机器人

· · 题解

思路

期望 DP。

分成撞不撞墙两种可能。

Arrive_{i,j} 表示从 (1,1) 出发,走 i+j-2 步,到达 (i,j) 的概率。 则撞墙的期望就是 x \times (1-Arrive_{i,j})

接下来考虑不撞墙的情况。

如果直接 DP,比较困难。因为是异或操作,可以考虑将每一位分开计算。

对于第 k 位,设 dp_{i,j} 表示从 (1,1) 出发,到达 (i,j),第 k 位异或是 1 的概率。

如果 a_{i,j} 的第 k 位是 0,则要使异或后使 1,只需要让上一个位置异或完是 1,即:

dp_{i,j} = dp_{i-1,j} + dp_{i,j-1}

同理,如果 a_{i,j} 的第 k 位是 1,则要使异或后使 1,只需要让上一个位置异或完是 0

所以此时: $$ dp_{i,j} = Arrive_{i-1,j} - dp_{i-1,j} + Arrive_{i,j-1} - dp_{i,j-1} $$ 将答案累加即可。 ```cpp #include<bits/stdc++.h> #define int long long using namespace std; bool Beginning; #define pb(x) push_back(x) #define mp(x,y) make_pair(x,y) #define se second #define fi first using PII=pair<int,int>; using PIB=pair<int,bool>; using PBI=pair<bool,int>; using PBB=pair<bool,bool>; using PDI=pair<double,int>; using PID=pair<int,double>; const int mod=1e9+7; namespace Memory_Love{ int read(){ int x=0; bool flag=1; char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();} while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return flag? x:-x;} template<typename T> void read(T &x){ bool flag=1; x=0; char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();} while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} x=(flag? x:-x);} template<typename T,typename ...Args> void read(T &Re,Args &...Res){read(Re),read(Res...);} template<typename T> void write(T x,char ch=0){if(x<0) x=-x,putchar('-'); static short s[35],top=-1; do{s[++top]=x%10;x/=10;}while(x); while(~top) putchar(s[top--]+48); if(ch) putchar(ch);} int gcd(int a,int b){return b==0? a:gcd(b,a%b);} int lcm(int a,int b){return a/gcd(a,b)*b;} int lowbit(int x){return (x&-x);} void MADD(int &x,int y,int mod){x=(x+y>=mod? x+y-mod:x+y);} int ksc(int a,int b,int p){int ans=0;while(b){if(b&1)MADD(ans,a,p);MADD(a,a,p);b>>=1;}return ans;} int ksm(int a,int b,int p){int ans=1%p;while(b){if(b&1)ans=ans*a%p;a=a*a%p;b>>=1;}return ans;} int exgcd(int a,int b,int &x,int &y){if(b==0){x=1,y=0;return a;}int d=exgcd(b,a%b,y,x);y-=a/b*x;return d;} int inv(int t){int x,y;exgcd(t,mod,x,y);return (x%mod+mod)%mod;} } using namespace Memory_Love; const int N=1e3+5; const int M=30; const int inv2=inv(2); int n,m,Wrong; int a[N][N]; int dp[N][N]; int Arrive[N][N]; int P(int i,int j,int x){return (x==1? dp[i][j]:(Arrive[i][j]-dp[i][j]));} int DP(int k) { int i,j; memset(dp,0,sizeof(dp)); dp[1][1]=(a[1][1]>>k&1); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { int x=(a[i][j]>>k&1); if(i!=1 || j!=1) dp[i][j]=(P(i-1,j,x^1)+P(i,j-1,x^1))*inv2%mod; } } return dp[n][m]; } bool Ending; signed main() { int i,j,ans=0; read(n,m,Wrong); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) a[i][j]=read(); } Arrive[1][1]=1; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(i!=1 || j!=1) Arrive[i][j]=(Arrive[i-1][j]+Arrive[i][j-1])*inv2%mod; } } (ans+=(1-Arrive[n][m])*Wrong)%=mod; for(i=0;i<=M;i++) (ans+=(1<<i)*DP(i))%=mod; write((ans+mod)%mod,'\n'); cerr<<"\nused:"<<(abs(&Ending-&Beginning)/1048576)<<"MB\n"; return 0; } ```