SGU 167 I-country(DP)
来源:互联网 发布:最初以太网的数据是 编辑:程序博客网 时间:2024/05/01 22:32
题意:给出一个n×m的矩阵,要在矩阵里选K个元素,另这些元素的和尽量大,并且任意两个元素相互可达并且它们之间到达的路径不能走两种以上的方向(比如每步只能走上或右)。
思路:一个非常非常恶心的dp……由于题中给出的要求,我们选的这个区域是有一定限制的,那就是这个图形不能凹进去,如果凹进去,一定会有两个元素之间要走至少3个方向才能到达。用dp[i][j][k][sx][sy][l]来表示状态,i表示前i行,j、k表示第i行选择j~k之间的元素,l表示当前选择元素的个数,sx和sy是用来表示当前行的延伸状态,用sx==0表示当前图形最左端可以向左延伸(即下一行可以选择1~j-1的元素,下面类似),sx==1表示只能向右延伸,用sy==0表示当前图形最右端可以向右延伸,sy==1表示只能向左延伸。记录路径的话,之前想暴力点每个状态记录准确的前一个状态,但是算了下,会爆内存,无奈,只好只记录了j和k,查找路径的时候在遍历一遍。。。感觉写查找路径比写状态转移还蛋疼……
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<set>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;struct Node{ int i,j,k,sx,sy,l,val; Node(){} Node(int a,int b,int c,int d,int e,int f,int g) {i=a;j=b;k=c;sx=d;sy=e;l=f;val=g;}}node;int a[20][20],sum[20][20],dp[16][16][16][2][2][230];int pre[16][16][16][2][2][230][2];int n,m,K;void cal(int i,int j,int k,int sx,int sy,int l){ int x=1,y=m; if(sx==1) x=j; if(sy==1) y=k; int sl,sr,tmp; for(int a=x;a<=k;++a) for(int b=max(a,j);b<=y;++b) { if(b-a+1+l>K) continue; if(a>j) sl=1; else sl=sx; if(b<k) sr=1; else sr=sy; tmp=dp[i][j][k][sx][sy][l]+sum[i+1][b]-sum[i+1][a-1]; if(dp[i+1][a][b][sl][sr][b-a+l+1]<=tmp) { dp[i+1][a][b][sl][sr][b-a+l+1]=tmp; pre[i+1][a][b][sl][sr][b-a+l+1][0]=j; pre[i+1][a][b][sl][sr][b-a+l+1][1]=k; if(b-a+l+1==K&&tmp>node.val) node=Node(i+1,a,b,sl,sr,b-a+l+1,tmp); } }}void getpath(int x,int l,int r,int sx,int sy,int cnt,int val){ if(cnt==0) return ; int L=pre[x][l][r][sx][sy][cnt][0]; int R=pre[x][l][r][sx][sy][cnt][1]; if(L!=-1&&R!=-1&&x!=1) for(int i=0;i<=sx;++i) for(int j=0;j<=sy;++j) { if(dp[x-1][L][R][i][j][cnt-(r-l+1)]+sum[x][r]-sum[x][l-1]==val) { getpath(x-1,L,R,i,j,cnt-(r-l+1),val-sum[x][r]+sum[x][l-1]); break; } } for(int y=l;y<=r;++y) printf("%d %d\n",x,y);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d%d",&n,&m,&K)) { for(int i=1;i<=n;++i) { sum[i][0]=0; for(int j=1;j<=m;++j) { scanf("%d",&a[i][j]); sum[i][j]=sum[i][j-1]+a[i][j]; } } memset(dp[1],0xff,sizeof(dp[1])); node.val=-1; for(int i=1;i<=m;++i) for(int j=i;j<=m;++j) if(j-i+1<=K) { dp[1][i][j][0][0][j-i+1]=sum[1][j]-sum[1][i-1]; pre[1][i][j][0][0][j-i+1][0]=pre[1][i][j][0][0][j-i+1][1]=-1; if(j-i+1==K&&sum[1][j]-sum[1][i-1]>node.val) node=Node(1,i,j,0,0,j-i+1,sum[1][j]-sum[1][i-1]); } for(int i=1;i<n;++i) { memset(dp[i+1],0xff,sizeof(dp[i+1])); for(int j=1;j<=m;++j) for(int k=j;k<=m;++k) if(k-j+1<=K) { dp[i+1][j][k][0][0][k-j+1]=sum[i+1][k]-sum[i+1][j-1]; pre[i+1][j][k][0][0][k-j+1][0]=pre[i+1][j][k][0][0][k-j+1][1]=-1; if(k-j+1==K&&sum[i+1][k]-sum[i+1][j-1]>node.val) node=Node(i+1,j,k,0,0,k-j+1,sum[i+1][k]-sum[i+1][j-1]); } for(int j=1;j<=m;++j) for(int k=j;k<=m;++k) for(int l=k-j+1;l<K;++l) { if(dp[i][j][k][0][0][l]!=-1) cal(i,j,k,0,0,l); if(dp[i][j][k][1][0][l]!=-1) cal(i,j,k,1,0,l); if(dp[i][j][k][0][1][l]!=-1) cal(i,j,k,0,1,l); if(dp[i][j][k][1][1][l]!=-1) cal(i,j,k,1,1,l); } } if(K) { printf("Oil : %d\n",node.val); getpath(node.i,node.j,node.k,node.sx,node.sy,K,node.val); } else printf("Oil : 0\n"); } return 0;}
0 0
- SGU 167 I-country(DP)
- SGU 384 Country 三角形
- sgu167:I-country
- SGU167 I-country
- URAL 1073 Square Country(DP)
- sgu - 520 - Fire in the Country(bfs + dfs + 博弈)
- SGU 168 Matrix DP
- SGU 195 树形DP
- sgu 168 Matrix DP
- SGU 104 DP
- SGU 131-状压dp
- SGU 256 Balloons(dp)
- sgu 495 概率dp
- SGU 134 树形DP
- SGU 223(状压+dp)
- I vow to thee My country 歌词
- 【树形DP】 hdu4340 Capturing a country
- hdu - 4340 - Capturing a country - 树形dp
- memcached与redis对性能对比
- Java多线程系列--“JUC集合”04之 ConcurrentHashMap
- 学之者生,用之者死——ACE历史与简评
- LA 5713 - Qin Shi Huang's National Road System(HDU 4081) MST
- 黄色警告: This text field does not specify an inputType or a hint
- SGU 167 I-country(DP)
- protobuf使用方法(c++为例)
- Programming Collective Intelligence
- CentOS-6.5 最新版出来了。种子
- 阿弥陀佛大心咒修持法
- 小白dp 10626 - Buying Coke
- 文字探险游戏,基于cmd显示.花了3个小时,技术非常不成熟
- Mac.OS.X.Programming
- 设计模式学习笔记——访问者模式