[TJOI2015]組合數學

Dilworth定理:最小鏈覆蓋數=最大點獨立集c++

這題要求最小鏈覆蓋,咱們能夠直接轉化爲最大獨立點集來求git

考慮DPspa

設$f[i][j]$表示當前在位置i,j時的答案,顯然$f[i][j]$能夠從$f[i-1][j]$和$f[i][j+1]$轉移過來(反鏈),可是若是要是最大獨立點集的話要求獨立,因此還能夠從$f[i-1][j+1]$這個沒法到達的地方轉移過來code

 

因此有:blog

$$f[i][j]=max\{f[i-1][j],f[i][j+1],f[i-1][j+1]+a[i][j]\}$$get

 

 1 //張家奇怎麼又AKIOI了呀,怎麼CSP也滿分啊...怎麼清北每天給他打電話啊...怎麼會有這麼強的人啊
 2 #include<bits/stdc++.h>
 3 #define int long long
 4 #define writeln(x)  write(x),puts("")
 5 #define writep(x)   write(x),putchar(' ')
 6 using namespace std;
 7 inline int read(){
 8     int ans=0,f=1;char chr=getchar();
 9     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
10     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
11     return ans*f;
12 }void write(int x){
13     if(x<0) putchar('-'),x=-x;
14     if(x>9) write(x/10);
15     putchar(x%10+'0');
16 }const int M = 1e3+5;
17 int f[M][M],a[M][M],n,m,T;
18 signed main(){
19     for(T=read();T--;){
20         n=read(),m=read();
21         memset(a,0,sizeof(a)),memset(f,0,sizeof(f));
22         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=read();
23         for(int i=1;i<=n;i++)for(int j=m;j>=1;j--)f[i][j]=max(max(f[i-1][j],f[i][j+1]),f[i-1][j+1]+a[i][j]);
24         cout<<f[n][1]<<endl;
25     }
26     return 0;
27 }
相關文章
相關標籤/搜索