P2258 子矩阵
作者:互联网
______________________________________________________________________________________________
想了一个四维DP,n^6,结果假了/哭
半搜索半dp,好有意思的题
————————————————————————————————————————————————————
#include<bits/stdc++.h> using namespace std; int n,m,num[17][17],f[17][17],le[17],lr[17][17],flg[17],bol[(1<<16)+1],r,c,nod,ans=0x3f3f3f3f; #define fr(i,c) for(int i=1;i<=c;i++) void pre(int zt) { memset(flg,0,sizeof(flg)); memset(le,0,sizeof(le)); memset(lr,0,sizeof(lr)); nod=0; for(int i=1;i<=n;i++){ if(zt%2==1)flg[++nod]=i; zt/=2; } fr(j,m)fr(i,nod-1)le[j]+=abs(num[flg[i]][j]-num[flg[i+1]][j]); for(int a=1;a<=m;a++)for(int b=1;b<a;b++)fr(i,nod)lr[a][b]+=abs(num[flg[i]][a]-num[flg[i]][b]); } void cl(int zt) { memset(f,0x3f,sizeof(f)); pre(zt); for(int i=1;i<=m;i++){ f[i][1]=le[i]; for(int j=2;j<=c;j++) for(int k=1;k<i;k++) f[i][j]=min(f[i][j],f[k][j-1]+le[i]+lr[i][k]); ans=min(f[i][c],ans); } } int main() { cin>>n>>m>>r>>c; fr(i,n)fr(j,m)cin>>num[i][j]; for(int i=0;i<=(1<<n)-1;i++) { int now=i,cnt=0; while(now) {if(now%2==1)cnt++;now/=2;} if(cnt==r)cl(i); } cout<<ans; }
标签:fr,le,P2258,17,int,矩阵,num,DP 来源: https://www.cnblogs.com/SFWR-YOU/p/11414251.html