zoukankan      html  css  js  c++  java
  • 2018多校第九场1004(HDU 6415) DP

    本以为是个找规律的题一直没找出来。。。

    题目:给你一个n*m的矩阵和1-n*m个数,问有多少种情况满足纳什均衡的点只有一个。纳什均衡点是指这个元素在所在行和所在列都是最大的。

    思路:吉老师直播的思路:(DP O(n^4)) 可以考虑从大到小的填充这个矩阵,设dp[cnt][i][j]是已经填充了cnt个数,i行可以放置数,j列可以放置数。

    有3个状态转移过程:

    1:选择在一个不是可放置行列交叉点的一个列上的某一点放置一个数,则放置之后会产生一个新的可放置行,每一列的可选择位置是n-i个,则dp[cnt+1][i+1][j]=dp[cnt][i][j]*j*(n-i);

    2:选择行上不是交叉点的一点,原理同上,dp[cnt+1][i][j+1]=dp[cnt][i][j]*i*(m-j);

    3:选择行和列的交叉点,则一共有i*j的交叉点,已经占用了cnt个,则可选择i*j-cnt+1个,dp[cnt+1][i][j]=dp[cnt][i][j]*(i*j-cnt+1);

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int dp[2][85][85];
    int n,m,mod;
    void update(int& a,long long c){
    	a=(a+c)%mod;
    }
    void solve(){
    	int Next,now=0;
    	memset(dp,0,sizeof(dp));
    	dp[0][1][1]=n*m;
    	for(int cnt=2;cnt<=n*m;cnt++){
    		Next=now^1;
    		memset(dp[Next],0,sizeof(dp[Next]));
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=m;j++){
    				if(dp[now][i][j]){
    					update(dp[Next][i+1][j],1ll*dp[now][i][j]*j*(n-i));
    					update(dp[Next][i][j+1],1ll*dp[now][i][j]*(m-j)*i);
    					update(dp[Next][i][j],1ll*dp[now][i][j]*(i*j-cnt+1));
    				}
    			}
    		now=Next;
    	}
    	printf("%d
    ",dp[now][n][m]);
    }
    int main(){
    	int T;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d%d",&n,&m,&mod);
    		solve();
    	}
    } 
    

      

  • 相关阅读:
    AMQP 介绍
    JMS 介绍
    SpringCloud 入门实战(12)--Zipkin(2)--安装使用
    SpringCloud 入门实战(11)--Zipkin(1)--简介
    Kafka 入门实战(3)--SpringBoot 整合 Kafka
    跨域访问方法介绍(9)--nginx 反向代理
    跨域访问方法介绍(8)--使用 WebSocket
    个人网站建好啦!
    Spring Boot配置Slf4j + log4j2
    SpringBoot 解决跨域,3种解决方案
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/9512875.html
Copyright © 2011-2022 走看看