日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)

發布時間:2023/12/3 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

序列

  • description
  • solution
  • code

description

題目描述

長度為nnn的序列,初始全為000,每次可以選擇?個數ai(1≤i≤l)a_i(1\le i\le l)ai?(1il),然后選擇連續aia_iai?個元素異或上111

求最少的次數,使得對于所有i(1≤i≤k)i(1\le i\le k)i(1ik)滿足第iii個位置是111,其他的位置都是000

輸入格式

第?行三個數n,m,kn,m,kn,m,k

第二行kkk個數分別表示x1,x2,...,xkx_1,x_2,...,x_kx1?,x2?,...,xk?

第三行lll個數分別表示a1,a2,...ala_1,a_2,...a_la1?,a2?,...al?

輸出格式

一個數表示答案,若不能達到輸出-1

樣例

10 2 3 1 2 6 10 4 2

數據范圍

n≤10000,k≤10,l≤100n\le 10000,k\le 10,l\le 100n10000,k10,l100

solution

異或常見有兩種處理

  • 0-1異或類,權值只有0,1

    顯然某位異或偶數次相當于沒操作,這就可以轉化成差分

  • 普通異或類

    按二進制拆位做,每位答案是獨立的

此題就是差分做法

e.g. 目標結果:1 0 0 1 1 0,相鄰兩位權值不同就要差分出來

操作一段長為aia_iai?的段,就相當于在pos,pos+aipos,pos+a_ipos,pos+ai?兩個位置異或111

本題kkk范圍極小,差分出來最多也就202020個位置

考慮從最后的狀態用最少操作數變成全000的初始狀態

這相當于一張n+1n+1n+1點姻緣圖,在差分2k2k2k個位置上有人,位置相差為aia_iai?的點對間有無向邊,人沿著邊移動,兩人相遇牽手成功離開,求最少走過的邊數,使得每個人都能找到自己的心動嘉賓

用bfs處理出,每個人到達所有點走過的最少邊數,到不了就置為inf

總人數不多,可以狀壓dp枚舉每次是哪兩個人牽手成功,轉移即可

code

#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define inf 0x3f3f3f3f queue < pair < int, int > > q; int n, k, l, cnt; int dis[22][100002]; int x[100002], a[105], c[25]; int dp[1 << 22];int dfs( int s ) {if( ! s ) return 0;if( dp[s] ^ inf ) return dp[s];int &ans = dp[s], x = __builtin_ctz( s );for( int y = cnt - 1;y > x;y -- )if( 1 << y & s ) {int t = dfs( s ^ ( 1 << y ) ^ ( 1 << x ) );ans = min( ans, t + dis[x][c[y]] );}return ans; }int main() {scanf( "%d %d %d", &n, &k, &l );for( int i = 1, pos;i <= k;i ++ ) {scanf( "%d", &pos );x[-- pos] = 1;}for( int i = 1;i <= l;i ++ )scanf( "%d", &a[i] );if( x[0] ) c[cnt ++] = 0;for( int i = 1;i <= n;i ++ )if( x[i] ^ x[i - 1] ) c[cnt ++] = i;if( cnt & 1 ) return ! printf( "-1" );memset( dp, 0x3f, sizeof( dp ) );memset( dis, 0x3f, sizeof( dis ) );for( int i = 0, j, d, pos;i < cnt;i ++ ) {dis[i][c[i]] = 0;q.push( make_pair( 0, c[i] ) );while( ! q.empty() ) {d = q.front().first, pos = q.front().second; q.pop();for( k = 1;k <= l;k ++ ) {j = pos + a[k];if( j <= n and dis[i][j] == inf )dis[i][j] = d + 1, q.push( make_pair( d + 1, j ) );j = pos - a[k];if( j >= 0 and dis[i][j] == inf )dis[i][j] = d + 1, q.push( make_pair( d + 1, j ) );}}}int ans = dfs( ( 1 << cnt ) - 1 );printf( "%d\n", ans == inf ? -1 : ans );return 0; }

總結

以上是生活随笔為你收集整理的[2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。