zoukankan      html  css  js  c++  java
  • [题解向] 正睿Round409

    ( m Link)

    然而泥萌没有权限是看不了题目的233.

    ( m T1)

    大概就是个map,脑残出题人认为(x,x)不属于有序二元组,我可qtmd。于是只拿了( m 60pts)

    int main(){
    	ios_base :: sync_with_stdio(false) ;
        cin.tie(0), cout.tie(0) ; cin >> N >> P ; int i ; 
    	for (i = 1 ; i <= N ; ++ i) cin >> base[i], base[i] %= P ; 
    	for (i = 1 ; i <= N ; ++ i) if (base[i]) M[expow(4 * base[i] % P, P - 2)] ++ ;
    	for (i = 1 ; i <= N ; ++ i){
    		int now = 1ll * base[i] * base[i] % P ; 
    		ans += M[now] ; if (4ll * now % P * base[i] % P == 1) -- ans ;  
    	}
    	cout << ans << endl ; return 0 ; 	
    } 
    

    ( m T2)

    先说自己的做法。

    发现其实就是在凑一个式子:

    [frac{sum a_ik_i}{Msum k_i}=frac{N}{M} ]

    然后稍微变个形:

    [sum a_ik_i=Ncdot sum k_i ]

    于是发现只要暴力背包就完了,最后判断一下(f_{k,N})是不是(=k)就做完了。

    int main(){
    	cin >> K >> N >> M ; int i, j ; dp[0] = 0 ; 
    	for (i = 1 ; i <= K ; ++ i) cin >> base[i] ; 
    	for (i = 1 ; i <= N * N ; ++ i) dp[i] = Inf ; 
    	for (i = 1 ; i <= K ; ++ i)
    		for (j = base[i] ; j <= N * N ; ++ j)
    			dp[j] = min(dp[j - base[i]] + 1, dp[j]) ; 
    	for (i = 1 ; i <= N ; ++ i) if (dp[i * N] == i) return cout << i, 0 ;
    	return -1 ;  
    }
    

    于是获得了( m 70pts)……但是用头想一想,发现并不对。因为可能(f_{k,N})这个状态的( m cost)可能是5,但是背包转移的时候只能记录最优状态,于是假设会记录4,那这个状态就挂掉了……对每个状态都开了个std :: set发现T掉了……

    正解是BFS。

    考虑把式子转化一下,就变成了

    [sum k_i(a_i-N)=0 ]

    大概就是考虑用已经凑出的和当做状态,那么实际上是在找一个环。于是每次转移的时候枚举放哪个新物品(新物品权值为(a_i-N))就完了。

    #define MAX 50000
    	cin >> K >> N >> M ; q.push(MAX) ; vis[MAX] = 1 ; int i ;
    	for (i = 1 ; i <= K ; ++ i) cin >> base[i], base[i] -= N ; 
    	while (!q.empty()){
    		int now = q.front() ; q.pop() ; 
    		if (now > M + MAX) continue ;
    		for (i = 1 ; i <= K ; ++ i){
    			if (now + base[i] == MAX){
    				cout << ans[now] + 1 << endl ; 
    				return 0 ; 
    			}
    			else if (!vis[now + base[i]]) 
    				vis[now + base[i]] = 1, ans[now + base[i]] = ans[now] + 1, q.push(now + base[i]) ;
    		}
    	}
    	cout << -1 << endl ; 
    

    正 解 暴 力, 菜 鸡 退 役。

    ( m T3)

    sb题,每个连通块都产生( m 1)的贡献当且仅当没有任何一个连通块是树。

    于是就变成了找树的问题……忘记前驱思考了nm老久,趁早退役算了= =

    void dfs(int now, int pre){
    	vis[now] = 1 ;
    	for (int k = head[now] ; k ; k = E[k].next){
    		if (to(k) == pre) continue ; 
    		if (to(k) == now) continue ; 
    		if (!vis[to(k)]) dfs(to(k), now) ; else ++ o ; 
    	} 
    }
    int main(){
    	cin >> N ; int i ; p = 1 ; 
    	for (i = 1 ; i <= N ; ++ i) fa[i] = i ; 
    	for (i = 1 ; i <= N ; ++ i) cin >> base[i], add(i, base[i]) ; 
    	for (i = 1 ; i <= N ; ++ i) if (fa[i] == i) ++ ans ;// cout << ans << endl ; 
    	for (i = 1 ; i <= N ; ++ i) if (!vis[i]) o = 0, dfs(i, 0), p = min(o, p) ; 
    	if (p) cout << ans << endl ; else cout << ans - 1 << endl ; 
    

    ( m T4)

    BZOJ4160.

    不可做题233

    题面:

    给定一张无向图,求给这张图定向成( m DAG)之后最长路最短是多少。(nleq 16)

    ( m{Sol~1})

    考虑直接(dp)(f_{s,u,v})表示考虑了点集(s),最长路端点是(u,v)的最小值。每次转移的时候枚举(u,v,w),从((u,v),(v,w))两个状态转移到((u,w))。复杂度(O(3^nn^3))

    1h没调出来

    ( m Sol~2)

    考虑证明一个二级定理:

    定理 (1.1)

    • 一张无向图定向成的( m DAG),当其最长路最短时,其最长路为( m X-1),其中( m X)表示不连通集覆盖数。也就是对于一张有向图图( m {V,E}),定义一种划分(P),使得划分出的每个集合中所有点不连通。

    考虑一种证明:

    • 首先一定有( m X-1geq maxL)。因为其上的每个点是连通的。
    • 其次我们考虑,如果每次删除全部出度为(0)点,放到一个集合里,那么一定合法,并且可以满足( m X=maxL+1)

    但其实这东西也可以直接用( m dilworth)定理的对偶定理证出来:

    定理 (2.1)( m dilworth)定理)

    ( m (X,≤))是一个有限偏序集,并令(m)是反链的最大的大小。则( m X)可以被划分成(m)个但不能再少的链。

    对偶一下:

    定理 (2.2):
    ( m (X,≤))是一个有限偏序集,并令(r)是其最大链的大小。则(X)可以被划分成(r)个但不能再少的反链。

    然后”反链“连接的是”不可比的点“,也就是本题中”不连通的点“。

    于是我们就可以快乐地状压了。

    int *g, *f ;
    int main(){
    	cin >> N >> M ; 
    	memset(f, 63, sizeof(f)) ; 
    	int u, v, i, j ; T = (1 << N) - 1 ;
    	for (i = 1 ; i <= M ; ++ i)
    		cin >> u >> v, -- u, -- v, E[u] |= (1 << v), E[v] |= (1 << u) ;
    	f[0] = 0, g[0] = 1 ; 
    	for (i = 0 ; i <= N ; ++ i) Sz[1 << i] = i ; 
    	for (i = 1 ; i <= T ; ++ i){
    		j = (i & (-i)) ;
    		if (!g[i ^ j]) continue ; 
    		if (E[Sz[j]] & (i ^ j)) continue ; 
    		g[i] = 1 ; 
    	}
    	for (i = 1 ; i <= T ; ++ i)
    		for (j = i ; j ; j = (j - 1) & i)
    			if (g[j]) f[i] = min(f[i], f[i ^ j] + 1) ; 
    	cout << f[T] - 1 << endl ; return 0 ;
    }
    
  • 相关阅读:
    hadoop3.2.0集群搭建的一些坑!
    springboot整合elasticJob实战(纯代码开发三种任务类型用法)以及分片系统,事件追踪详解
    Flask接口返回JSON格式数据自动解析
    Struts2--国际化
    Struts2--标签tag
    Struts2-OGNL
    Struts2--拦截器Interceptor
    Struts2--struts.xml详解
    Spring--事务管理
    Spring--JDBC
  • 原文地址:https://www.cnblogs.com/pks-t/p/11748764.html
Copyright © 2011-2022 走看看