[noip2014]子矩阵(dfs+dp)
2017-10-30 21:57
369 查看
题目:
我是超链接题解:
一眼dp?那我就dfs出我选哪几行,然后f[i][j]表示前i列选j列的最小值(必须选i)
转移的话f[i][j]=min{f[k][j-1]+qz[i]} 1<=k<i
这个权值怎么办呢?权值其实分成两部分:横向+纵向
纵向在dfs出来之后就可以定了,用be[i]表示i这一列的上下差
横向呢?dif[i][j]表示i列和j列的权值差
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 1e9 using namespace std; int mp[20][20],a[20],f[20][20],ans=INF,n,m,r,c,dif[20][20],be[20]; bool check() { int i,j,k; memset(f,0x7f,sizeof(f)); memset(dif,0,sizeof(dif)); memset(be,0,sizeof(be)); for (i=1;i<=m;i++) for (j=2;j<=r;j++) be[i]+=abs(mp[a[j]][i]-mp[a[j-1]][i]); for (i=1;i<=m;i++) for (j=i+1;j<=m;j++) for (k=1;k<=r;k++) dif[i][j]+=abs(mp[a[k]][j]-mp[a[k]][i]); for (i=1;i<=m;i++) f[i][1]=be[i]; for (j=2;j<=c;j++) for (i=2;i<=m;i++) for (k=1;k<i;k++) f[i][j]=min(f[i][j],f[k][j-1]+dif[k][i]+be[i]); for (i=c;i<=m;i++) ans=min(ans,f[i][c]); } void dfs(int t,int< ed8d /span> last) { if (n-last+1<r-t) return; if (t>r){check();return;} for (int i=last;i<=n;i++) {a[t]=i;dfs(t+1,i+1);} } int main() { scanf("%d%d%d%d",&n,&m,&r,&c); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&mp[i][j]); dfs(1,1); printf("%d",ans); }
相关文章推荐
- 【vijos P1914】【codevs 3904】[NOIP2014 普及组T4]子矩阵(dfs+状压dp)
- [NOIP2014][vijos1914]子矩阵(dp)
- 洛谷 P2258 NOIP2014普及组 T4 子矩阵 DFS+DP
- 2014ACM/ICPC亚洲区北京站hdu5112~5122(dp,dfs)
- 【NOIP2014】飞扬的小鸟 背包dp
- NOIP2014:飞扬的小鸟 - DP
- 【DFS】【最短路】【spfa】【BFS】洛谷P2296 NOIP2014提高组 day2 T2 寻找道路
- NOIP 2014 普及组 T4 子矩阵
- 【noip2014普及】子矩阵
- [NOIP模拟题][DFS][DP]
- NOIP2014 联合权值 解题报告(乱搞(据说这道题是树状dp,感觉好像是))
- 【DP】UOJ#17 【NOIP2014】飞扬的小鸟
- 【DFS】NOIP2014Day1T2[联合权值]题解
- [jzoj]3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)(DP嵌套dfs【快】或DP【慢】)
- LuoguP1941[NOIP2014] 飞扬的小鸟 解题报告【背包型DP】
- NOIP2014 飞扬的小鸟 解题报告(DP)
- 【NOIp 2014】【二维dp】飞扬的小鸟
- 联合权值 noip2014 dfs
- NOIP2014 子矩阵
- jzoj5336 【NOIP2017提高A组模拟8.24】提米树 (dfs序dp,奇异姿势dp)