[题解][洛谷P1373 小a和uim之大逃离]

这是一道DP题,大家应该都可以看出来。这题是与地图有关的,所以我的f数组首先带上坐标。

再看k是<=15,所以我的第一个f数组是五维的f[i][j][k][l][1/0],代表在第(i,j)的位置第一个人有k个,第二个人有l个,0是第一个人选,1是第二个人选;的方案数,但是显然时空复杂度都不能接受。

我们再看题目,最终是否是我们的答案只与相对大小有关,所以我们把第三维和第四维合并为两人相差了多少,第一个人捡就加,第二个人捡就减,然后从前往后转移即可。

f[i][j][l][0]=(ll)(f[i][j][l][0]+f[i][j-1][(l-Map[i][j]+k+1)%(k+1)][1])%mod;
f[i][j][l][0]=(ll)(f[i][j][l][0]+f[i-1][j][(l-Map[i][j]+k+1)%(k+1)][1])%mod;
f[i][j][l][1]=(ll)(f[i][j][l][1]+f[i][j-1][(l+Map[i][j])%(k+1)][0])%mod;
f[i][j][l][1]=(ll)(f[i][j][l][1]+f[i-1][j][(l+Map[i][j])%(k+1)][0])%mod;


最后贴上代码:~~~

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define N 805
 4 #define K 16
 5 #define mod 1000000007
 6 using namespace std;
 7 int n,m,k,f[N][N][K][2],ans,Map[N][N];
 8 int read()
 9 {
10     int x=0,f=1;char c=getchar();
11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
12     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
13     return x*f;
14 }
15 int main()
16 {
17     n=read();m=read();k=read();
18     for(int i=1;i<=n;++i)
19         for(int j=1;j<=m;++j)
20             Map[i][j]=read(),f[i][j][Map[i][j]][0]=1;
21     for(int i=1;i<=n;++i)
22         for(int j=1;j<=m;++j)
23             for(int l=0;l<=k;++l)
24             {
25                 f[i][j][l][0]=(ll)(f[i][j][l][0]+f[i][j-1][(l-Map[i][j]+k+1)%(k+1)][1])%mod;
26                 f[i][j][l][0]=(ll)(f[i][j][l][0]+f[i-1][j][(l-Map[i][j]+k+1)%(k+1)][1])%mod;
27                 f[i][j][l][1]=(ll)(f[i][j][l][1]+f[i][j-1][(l+Map[i][j])%(k+1)][0])%mod;
28                 f[i][j][l][1]=(ll)(f[i][j][l][1]+f[i-1][j][(l+Map[i][j])%(k+1)][0])%mod;
29             }
30     for(int i=1;i<=n;++i)
31         for(int j=1;j<=m;++j)
32             ans=(ans+f[i][j][0][1])%mod;
33     printf("%lld\n",ans);
34     return 0;
35 }

 



我代码丑,各位老爷将就着看吧~~~


posted @ 2018-07-21 16:04  fanyujun  阅读(121)  评论(0编辑  收藏  举报