• 【滚动数组】【状压dp】Gym


    f(i,j,S)表示到(i,j),且经由的路径上的颜色集合为S的价值的最小值,从上方和左方转移过来即可。

    要注意,内存不足,需要滚动数组优化,即使用了map,还是需要。

    路径输出的时候,可以再跑一遍dp,这样就不用再开一个大数组了。

    我的写法比较菜。卡了常数

    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    int w[401][401],c[401][401];
    typedef pair<int,int> Point;
    map<int,int>f[401][401];
    typedef pair<int,Point> data;
    typedef map<int,int>::iterator ITER;
    map<int,data>g[401][401];
    int n,K,W;
    int calc(int x)
    {
    	int res=0;
    	while(x)
    	  {
    	  	res+=(x&1);
    	  	x>>=1;
    	  }
    	return res;
    }
    Point path[1001];
    int e;
    int main()
    {
    	scanf("%d%d%d",&n,&K,&W);
    	for(int i=1;i<=n;++i)
    	  for(int j=1;j<=n;++j)
    	    scanf("%d",&w[i][j]);
    	for(int i=1;i<=n;++i)
    	  for(int j=1;j<=n;++j)
    	    scanf("%d",&c[i][j]);
    	if(w[1][1]>W)
    	  {
    	  	puts("-1");
    	  	return 0;
    	  }
    	f[1][1][1<<(c[1][1]-1)]=w[1][1];
    	for(int i=1;i<=n;++i){
    	  for(int j=1;j<=n;++j)
    	    {
    	      if(i>1 && j>1)
    	        {
    	          for(ITER it=f[i-1][j].begin();it!=f[i-1][j].end();++it)
    	            {
    	              int nS=(*it).first|(1<<(c[i][j]-1)),tmp=(*it).second+w[i][j];
    	              if(f[i][j].find(nS)==f[i][j].end())
    	                {
    	                  if(tmp<=W)
    					    {
    					      f[i][j][nS]=tmp;
    					      g[i][j][nS]=data((*it).first,Point(i-1,j));
    					    }
    	                }
    	              else if(f[i][j][nS]>tmp)
    	                {
    	                  f[i][j][nS]=tmp;
    					  g[i][j][nS]=data((*it).first,Point(i-1,j));
    	                }
    	            }
    	          for(ITER it=f[i][j-1].begin();it!=f[i][j-1].end();++it)
    	            {
    	              int nS=(*it).first|(1<<(c[i][j]-1)),tmp=(*it).second+w[i][j];
    	              if(f[i][j].find(nS)==f[i][j].end())
    	                {
    	                  if(tmp<=W)
    					    {
    					      f[i][j][nS]=tmp;
    					  	  g[i][j][nS]=data((*it).first,Point(i,j-1));
    					    }
    	                }
    	              else if(f[i][j][nS]>tmp)
    	                {
    	                  f[i][j][nS]=tmp;
    					  g[i][j][nS]=data((*it).first,Point(i,j-1));
    	                }
    	            }
    	        }
    	      else if(i==1 && j>1)
    	        {
    	          for(ITER it=f[i][j-1].begin();it!=f[i][j-1].end();++it)
    	            {
    	              int nS=(*it).first|(1<<(c[i][j]-1)),tmp=(*it).second+w[i][j];
    	              if(f[i][j].find(nS)==f[i][j].end())
    	                {
    	                  if(tmp<=W)
    					    {
    					      f[i][j][nS]=tmp;
    					  	  g[i][j][nS]=data((*it).first,Point(i,j-1));
    					    }
    	                }
    	              else if(f[i][j][nS]>tmp)
    	                {
    	                  f[i][j][nS]=tmp;
    					  g[i][j][nS]=data((*it).first,Point(i,j-1));
    	                }
    	            }
    	        }
    	      else if(i>1 && j==1)
    	        {
    	          for(ITER it=f[i-1][j].begin();it!=f[i-1][j].end();++it)
    	            {
    	              int nS=(*it).first|(1<<(c[i][j]-1)),tmp=(*it).second+w[i][j];
    	              if(f[i][j].find(nS)==f[i][j].end())
    	                {
    	                  if(tmp<=W)
    					    {
    					      f[i][j][nS]=tmp;
    					      g[i][j][nS]=data((*it).first,Point(i-1,j));
    					    }
    	                }
    	              else if(f[i][j][nS]>tmp)
    	                {
    	                  f[i][j][nS]=tmp;
    					  g[i][j][nS]=data((*it).first,Point(i-1,j));
    	                }
    	            }
    	        }
    	    }
    	  if(i>=3)
    	    {
    	      for(int j=1;j<=n;++j)
    	        {
    	          f[i-2][j].clear();
    //	          g[i-2][j].
    			} 
    	    }
    	}
    	int ans=2147483647;
    	int anS;
    	for(ITER it=f[n][n].begin();it!=f[n][n].end();++it)
    	  {
    	  	int tmp=calc((*it).first);
    	  	if(tmp<ans)
    	  	  {
    	  	  	ans=tmp;
    	  	  	anS=(*it).first;
    	  	  }
    	  }
    	if(ans==2147483647)
    	  puts("-1");
    	else
    	  {
    	  	printf("%d
    ",ans);
    	  	data U=data(anS,Point(n,n));
    	  	path[++e]=Point(n,n);
    	  	while(U.second!=Point(1,1))
    	  	  {
    	  	  	U=g[U.second.first][U.second.second][U.first];
    	  	  	path[++e]=U.second;
    	  	  }
    	  	for(int i=e;i>=1;--i)
    	  	  printf("%d %d%c",path[i].first,path[i].second,i==1 ? '
    ' : ' ');
    	  }
    	return 0;
    }
  • 相关阅读:
    IOS 网络请求中设置cookie
    七牛云存储 报错的问题
    理解RESTful架构
    关于APP接口设计
    WKWebView与Js实战(OC版)
    WKWebView API精讲(OC)
    iOS完整App资源收集
    WKWebView新特性及JS交互
    苹果app审核的规则总结
    Struts2实现文件的上传与动态下载功能。
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6287966.html
Copyright © 2020-2023  润新知