6415 Rikka with Nash Equilibrium

http://acm.hdu.edu.cn/showproblem.php?pid=6415

题意:已知n, m, k,求仅有一个  pure strategy Nash equilibriums(六花选行号, 勇太选列号,对应数字即为结果,psne即对于当前矩阵,两人都无法通过单独改变自己的选择增大结果)的n*m矩阵有几种,答案模k。

(1. Each integer in [1,nm] occurs exactly once in A.
2. The game has at most one pure strategy Nash equilibriums.)

思路:dp[i][j][k]表示(从大到小)放置第i个数字于某j行k列合法。

其中,dp[1][1][1] = (n*m) , i|2...n*m, j|1...n, k|1...m; 

j*k > i-1时有如下

dp[i][j][k] = (dp[i-1][j-1][k] * k * (n-j+1)//贡献一个额外的可行列, 可行列k*可行列上未使用行(n -(j-1))。

              +  dp[i-1][j][k-1] * j * (m-k+1)//同上。

              +  dp[i-1][j][k]    * (j*k - (i-1))//无贡献(置于交叉点上), j*k个可行交叉点 - (i-1)个已使用交叉点。

ps:中途转long long每次只取一次模可大大减少耗时。

 

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include<algorithm>
 4 #include <iostream>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include  <stdio.h>
 8 #include   <math.h>
 9 #include   <time.h>
10 #include   <vector>
11 #include   <bitset>
12 #include    <queue>
13 #include      <map>
14 #include      <set>
15 using namespace std;
16 
17 typedef  long long  ll;
18 const int N = 80+5;
19 int dp[N*N][N][N];
20 
21 int main()
22 {
23     int t;
24     scanf("%d",&t);
25     while(t--){
26         int n, m, mod;
27         scanf("%d%d%d", &n, &m, &mod);
28         dp[1][1][1] = n*m%mod;
29         for(int i = 2; i <= n*m; i++){
30             for(int j = 1;j <= n; j++){
31                 for(int k = 1;k <= m; k++){
32                     if(j*k > i-1){
33                         dp[i][j][k] = 1ll*dp[i-1][j-1][k] * k * (n-j+1)%mod;
34                         dp[i][j][k] = (dp[i][j][k] + 1ll*dp[i-1][j][k-1] * j * (m-k+1)%mod)%mod;
35                         dp[i][j][k] = (dp[i][j][k] + 1ll*dp[i-1][j][k] * (j*k - (i-1))%mod)%mod;
36                     }
37                 }
38             }
39         }
40         printf("%d\n",dp[n*m][n][m]);
41     }
42     return 0;
43 }
View Code

算出样例之后就沉浸于递归的思路无法自拔,然而。。。递归->记忆化搜索->(递推?)动态规划。。。想到递归之后上手写一下记忆化搜索的话可能就想到dp了,脑速不够还不动手就很不ok。。。 


就算不推dp,直接记忆化搜索也能过,啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊。。。为啥窝不写啊啊啊啊啊啊啊啊啊啊啊啊啊。。。总是拿窝的算法太暴力当借口不写题到最后毛都不会。。。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll mod,n,m;
 5 const ll N=6405;
 6 ll dp[85][85][85*85];
 7 ll dfs(ll x,ll y,ll z){//占领了x行,y列。已经放进去了z个数字
 8     if(dp[x][y][z]!=-1) return dp[x][y][z];
 9     ll tmp=0;
10     if(x<n) tmp=(tmp+y*(n-x)%mod*dfs(x+1,y,z+1))%mod;
11     if(y<m) tmp=(tmp+x*(m-y)%mod*dfs(x,y+1,z+1))%mod;
12     if(x*y>z) tmp=(tmp+(x*y-z)%mod*dfs(x,y,z+1))%mod;
13     return dp[x][y][z]=tmp;
14 }
15 int main()
16 {
17     ll t;
18     scanf("%lld",&t);
19     while(t--){
20         memset(dp,-1,sizeof(dp));
21         scanf("%lld%lld%lld",&n,&m,&mod);
22         dp[n][m][n*m]=1;
23         ll ans=m*n%mod*dfs(1,1,1)%mod;
24         printf("%lld\n",ans);
25     }
26 }
View Code

(但是真的很慢,4000+ms卡过。)

hdu 6406 Taotao Picks Apples

思路:二分吖upper_bound吖~模拟吖!!!(手残党,WA地一声哭出来。)

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include<algorithm>
 4 #include <iostream>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include  <stdio.h>
 8 #include   <math.h>
 9 #include   <time.h>
10 #include   <vector>
11 #include   <bitset>
12 #include    <queue>
13 #include      <map>
14 #include      <set>
15 using namespace std;
16 
17 typedef  long long  ll;
18 const int N = 1e5+5;
19 int a[N], premax[N], tmp[N], vis[N], t, n, m, l;
20 vector <int> di[N];
21 
22 void init(){
23     memset(a, 0, sizeof a);
24     memset(premax, 0, sizeof premax);
25     memset(tmp, 0, sizeof tmp);
26     memset(vis, 0, sizeof vis);
27     scanf("%d%d", &n,&m);
28     for(int i = 0; i <= n; i++) di[i].clear();
29     int maxx = -1;
30     l = 0;
31     for(int i = 1; i <= n; i++){
32         scanf("%d", &a[i]);
33         if(a[i] > maxx){
34             vis[i] = 1;
35             maxx = premax[i] = tmp[l++] = a[i];
36         }
37         else premax[i] = maxx;
38     }
39     int r = 0;
40     for(int i = 1; i <= n; i++){
41         if(vis[i] == 1) r = i;
42         else{
43             int sz = di[r].size();
44             if(sz == 0 || (sz > 0 && a[i] > di[r][sz-1]))
45                 di[r].push_back(a[i]);
46         }
47     }
48 }
49 void solve(){
50     init();
51     for(int i = 1, p, q; i <= m; i++){
52         scanf("%d%d", &p,&q);
53         if(q == premax[p] || (!vis[p] && q < premax[p])) printf("%d\n", l);
54         else if(!vis[p] && q > premax[p]){
55             int x = l - (upper_bound(tmp, tmp+l, q) - upper_bound(tmp, tmp+l, premax[p]));
56             printf("%d\n", x+1);
57         }
58         else if(vis[p] && q > premax[p])
59             printf("%d\n", l - (upper_bound(tmp, tmp+l, q) - upper_bound(tmp, tmp+l, premax[p])));
60         else if(vis[p] && q < premax[p]){
61             if(p == 1 || q > premax[p-1])
62                 printf("%d\n", l + (di[p].end() - upper_bound(di[p].begin(), di[p].end(), q)));
63             else {
64                 int x = di[p].end() - upper_bound(di[p].begin(), di[p].end(), premax[p-1]);
65                 printf("%d\n", l+x-1);
66             }
67         }
68     }
69 }
70 
71 int main(){
72     for(scanf("%d", &t); t; t--) solve();
73     return 0;
74 }
View Code

 

 

hdu6400 Parentheses Matrix

思路:牺牲小我,拯救全家。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include<algorithm>
 4 #include <iostream>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include  <stdio.h>
 8 #include   <math.h>
 9 #include   <time.h>
10 #include   <vector>
11 #include   <bitset>
12 #include    <queue>
13 #include      <map>
14 #include      <set>
15 using namespace std;
16 
17 int main()
18 {
19     int _, h,w;
20     char ans[205][205];bool rev = 0;
21     for(scanf("%d", &_);_;_--){
22         rev = 0;
23         memset(ans, 0, sizeof(ans));
24         scanf("%d%d", &h,&w);
25         if((h&1) && (w&1)){
26             for(int i = 0; i < h; i++){
27                 for(int i = 0; i < w; i++) printf("(");
28                 puts("");
29             }
30         }
31         else if((h&1) || (w&1)){
32             if(h&1){
33                 for(int i = 0; i < h; i++){
34                     for(int j = 0; j < w; j+=2){
35                         ans[i][j] = '(';
36                         ans[i][j+1] = ')';
37                     }
38                 }
39             }
40             else if(w&1){
41                 for(int i = 0; i < w; i++){
42                     for(int j = 0; j < h; j+=2){
43                         ans[j][i] = '(';
44                         ans[j+1][i] = ')';
45                     }
46                 }
47             }
48             //for(int i = 0; i < h; i++) puts(ans[i]);
49         }
50         else {
51             if(h > w){
52                 swap(h, w);
53                 rev = 1;
54             }
55             if(h == 2){
56                 for(int i = 0; i < w; i++){
57                         ans[0][i] = '(';
58                         ans[1][i] = ')';
59                 }
60             }
61             else if(h == 4){
62                 for(int i = 0; i < w; i++) ans[0][i] = '(', ans[h-1][i] = ')';
63                 for(int i = 0; i < w/2; i++) ans[1][i] = ')', ans[2][i] = '(';
64                 for(int i = w/2; i < w; i++) ans[1][i] = '(', ans[2][i] = ')';
65             }
66             else{
67                 for(int i = 0; i < w; i++) ans[0][i] = '(', ans[h-1][i] = ')';
68                 for(int i = 1; i < h-1; i+=2) for(int j = 0; j < w; j+=2) ans[i][j] = '(', ans[i][j+1] = ')';
69                 for(int i = 2; i < h; i+=2){
70                     ans[i][0] = '('; ans[i][w-1] = ')';
71                     for(int j = 1; j < w-1; j+=2) ans[i][j] = '(', ans[i][j+1] = ')';
72                 }
73 
74             }
75         }
76         if(!rev)
77             for(int i = 0; i < h; i++) puts(ans[i]);
78         else{
79             for(int i = 0; i < w; i++){
80                 for(int j = 0; j < h; j++)
81                     putchar(ans[j][i]);
82                 puts("");
83             }
84         }
85     }
86     return 0;
87 }
View Code

 

posted on 2018-08-21 10:47  雪藤  阅读(229)  评论(0编辑  收藏  举报