zoukankan      html  css  js  c++  java
  • 2018 MUltiU 9 dp / 8 upper_bound ; 构造?/

    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
    ",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
    ",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
    ", 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
    ", x+1);
    57         }
    58         else if(vis[p] && q > premax[p])
    59             printf("%d
    ", 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
    ", 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
    ", 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
  • 相关阅读:
    Java 基础知识(五)
    Java 基础知识(四)
    Java 基础知识(三)
    Java 基础知识(二)
    python 默认参数潜在的问题
    python中统计计数的几种方法和Counter的介绍
    简单的总结一下到底什么是python
    python中的__solots__方法
    python中生成器和迭代器以及可迭代对象的区别
    游览器访问一个网址的全过程
  • 原文地址:https://www.cnblogs.com/curieorz/p/9510039.html
Copyright © 2011-2022 走看看