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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 4437. 【HNOI2016模拟4.10】线性代数与逻辑

發(fā)布時(shí)間:2025/3/15 编程问答 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 4437. 【HNOI2016模拟4.10】线性代数与逻辑 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Description

Input

Output

Sample Input

Sample Output

Data Constraint

Solution

  • (附:本人第 100 篇博文,為 OI 事業(yè)奮斗,多多支持~)。

  • 這道題的題面讓人感到云里霧里,但是經(jīng)過仔細(xì)的抽絲剝繭之后就會發(fā)現(xiàn)這真“模型”。

  • 首先, X 矩陣是由 Y 向量構(gòu)造出來的: X[i][j]=y[i]?xor?y[j] 。

  • 所以當(dāng) X 矩陣的對角線上存在 1 時(shí),就不合法了,輸出“-1”(異或運(yùn)算的性質(zhì))。

  • 又由于 X 矩陣的對稱性,我們只需處理對角線上方的答案,最后乘2即可。

  • 我們發(fā)現(xiàn),如果每一位 A[i][j]=1 的話,因?yàn)?A?||?!X=!O ,所以要求 X[i][j]=1 。

  • 所以相當(dāng)于 y[i]y[j] ,則點(diǎn) i 向點(diǎn) j 連一條無向邊,表示點(diǎn) i 和點(diǎn) j 為對立點(diǎn)。

  • 這樣便構(gòu)出了一張二分圖(若有奇環(huán)則判為“-1”),用 Friend-Enemy 并查集 維護(hù)出聯(lián)通塊。

  • 那么最后答案是所有聯(lián)通塊的 0 的個(gè)數(shù)乘 1 的個(gè)數(shù) 。

  • 為了保證答案最優(yōu),對于這些連通塊,我們可以做一遍類似背包的 O(N2)DP

  • 設(shè) F[i][j] 表示做到第 i 個(gè)連通塊、0 的個(gè)數(shù)為 j1 的最大個(gè)數(shù) ,轉(zhuǎn)移顯然。

  • 由于 X 取過反 , 1 的最大個(gè)數(shù)即為所求。

  • 又由于開始的狀態(tài)有 1 ,會計(jì)算重復(fù),我們減去算出的 連邊條數(shù)(意義相同) 即可。

  • 那么連邊、DP復(fù)雜度相等,這樣總時(shí)間復(fù)雜度即為 O(N2)

Code

#include<cstdio> #include<cstring> #define clr(x,y) memset(x,y,sizeof(x)); using namespace std; const int N=1001; int n,tot,num; int first[N],next[N<<1],en[N<<1]; int f[N][N],g[N],h[N][2],fa[N]; bool judge; bool a[N][N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline int max(int x,int y) {return x>y?x:y; } inline int get(int x) {if(fa[x]==x) return x;return fa[x]=get(fa[x]); } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y; } inline void init_link() {tot=num=0;clr(first,0);clr(g,-1);clr(h,0);clr(f,-1);for(int i=1;i<=n;i++) fa[i]=i;for(int i=1;i<n;i++)for(int j=i+1;j<=n;j++)if(a[i][j]){insert(i,j);insert(j,i);int f1=get(i),f2=get(j);if(f1!=f2) fa[f1]=f2;} } inline void dfs(int x,int y) {h[num][g[x]]++;for(int i=first[x];i;i=next[i])if(en[i]!=y){if(g[en[i]]==g[x]){judge=true;return;}if(g[en[i]]!=-1) continue;g[en[i]]=g[x]^1;dfs(en[i],x);if(judge) return;} } inline void dp() {int ans=f[0][0]=0;for(int i=1;i<=num;i++)for(int j=0;j<=n;j++){int x=h[i][0],y=h[i][1];if(j>=x && f[i-1][j-x]!=-1) f[i][j]=max(f[i][j],f[i-1][j-x]+y);if(j>=y && f[i-1][j-y]!=-1) f[i][j]=max(f[i][j],f[i-1][j-y]+x);}for(int j=0;j<=n;j++) ans=max(ans,f[num][j]*j);printf("%d\n",(ans<<1)-tot); } inline void work() {n=read();for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) a[i][j]=read();for(int i=1;i<=n;i++)if(a[i][i]){printf("-1\n");return;}init_link();for(int i=1;i<=n;i++)if(get(i)==i){judge=g[i]=0,num++;dfs(i,0);if(judge){printf("-1\n");return;}}dp(); } int main() {int T=read();while(T--) work();return 0; }

總結(jié)

以上是生活随笔為你收集整理的JZOJ 4437. 【HNOI2016模拟4.10】线性代数与逻辑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。