【NOIP2014】子矩阵
生活随笔
收集整理的這篇文章主要介紹了
【NOIP2014】子矩阵
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這題如果按暴力做只有一半分,最大時間復雜度為O(C(16,8)*C(16,8)); 很容易算出超時;
我們可以發現如果直接dp會很難想,但是知道選哪幾行去dp就很好寫狀態轉移方程:
? ? ?dp[i][j]=min(dp[i][j],dp[k][j-1]+a[i]+b[k][i]);
其中dp[i][j]表示 前i列里選j列的子矩陣最大分值
? ? ?a[i]表示 第i列選到的行的總差值
? ? ?b[k][i]表示選到的每一行第k列和第i列之間的差值
我們只要枚舉 行 然后dp一次,取最小值即可 這樣最大時間復雜度就成了O(C(8,16)*n3);
最后附上我弱弱的pascal代碼:?
1 var 2 i,j,k,n,m,n1,m1,ans:longint; 3 dp,a,f:array[0..16,0..16] of longint; 4 hc:array[0..16,1..16,1..16] of longint; 5 b,lc:array[0..17] of longint; 6 function min(a,b:longint):longint; 7 begin 8 if a>b then min:=b 9 else min:=a; 10 end; 11 procedure ddp; 12 var 13 i,j,k,max:longint; 14 begin 15 fillchar(f,sizeof(f),0); 16 fillchar(lc,sizeof(lc),0); 17 fillchar(dp,sizeof(dp),0); 18 for i:=1 to m do 19 for j:=1 to n1-1 do 20 lc[i]:=lc[i]+abs(a[b[j+1],i]-a[b[j],i]); 21 for i:=1 to m do 22 for j:=i+1 to m do 23 for k:=1 to n1 do 24 f[i,j]:=f[i,j]+hc[b[k],i,j]; 25 for i:=1 to m do 26 dp[i,1]:=lc[i]; 27 for i:=2 to m do 28 for j:=2 to m1 do 29 if i>=j then 30 begin 31 dp[i,j]:=maxlongint; 32 for k:=j-1 to i-1 do 33 dp[i,j]:=min(dp[i,j],dp[k,j-1]+lc[i]+f[k,i]); 34 end; 35 for i:=m1 to m do 36 if dp[i,m1]<ans then ans:=dp[i,m1]; 37 end; 38 procedure jw(ii:longint); 39 begin 40 inc(b[ii]); 41 if ii>=0 then 42 if b[ii]>(n-n1+ii) then 43 begin 44 jw(ii-1); 45 b[ii]:=b[ii-1]+1; 46 end; 47 end; 48 begin 49 read(n,m,n1,m1); 50 for i:=1 to n do 51 for j:=1 to m do 52 begin 53 read(a[i,j]); 54 for k:=1 to j-1 do 55 hc[i,k,j]:=abs(a[i,j]-a[i,k]); 56 end; 57 for i:=1 to n1 do 58 b[i]:=i; 59 ans:=100000000; 60 while b[0]=0 do 61 begin 62 ddp; 63 jw(n1); 64 end; 65 write(ans); 66 end.?
轉載于:https://www.cnblogs.com/WQHui/p/5869500.html
總結
以上是生活随笔為你收集整理的【NOIP2014】子矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文本查询程序
- 下一篇: phalcon: 资源文件管 理 引入c