SRM 554 DIV2

第一题:

题意:有两种颜色的砖块,红色和蓝色。给你两种砖块的高度和数量,要求砖块只能放在与其不同颜色的砖块上面。问一共可以叠出多少种高度。

题解:暴力枚举。

代码:

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;
set<int>  s;
void dfs(int rc,int rh,int bc,int bh,int high,int color)
{
     if(color==0&&rc>0)
     {
         s.insert(high+rh);
         dfs(rc-1,rh,bc,bh,high+rh,1);
     }
     else if(color==1&&bc>0)
     {
        s.insert(high+bh);
        dfs(rc,rh,bc-1,bh,high+bh,0);
     }
}
class TheBrickTowerEasyDivTwo {
public:
	int find(int redCount, int redHeight, int blueCount, int blueHeight) {
		s.clear();
		dfs(redCount,redHeight,blueCount,blueHeight,0,0);
		dfs(redCount,redHeight,blueCount,blueHeight,0,1);
		return s.size();
	}
};



第二题:

题意:有n个不同高度的砖块排成一列,要求两块砖块之间的距离不小于两者中最大的高度,让你重新给砖块排序,使得第1块到最后1块之间的距离最小。距离相同输出字典序最小的。

题解:求出全排列然后计算距离,保留最小值。ps:求全排列可以用STL

代码:

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;
vector<int> num,temp;
int check()
{
    int summ=0;
    int len=num.size();
    for(int i=1;i<len;++i)
         summ+=max(temp[num[i]],temp[num[i-1]]);
    return summ;
}
class TheBrickTowerMediumDivTwo {
public:
	vector <int> find(vector <int> heights) {
	    vector<int> ans;
	    ans.clear();
	    num.clear();
	    temp.clear();
		int len=heights.size();
		if(len==1)
		{
		    ans.push_back(0);
		    return ans;
		}
		for(int i=0;i<len;++i)
		{
		    num.push_back(i);
		    temp.push_back(heights[i]);
		}
		int minn=99999;
		do
		{
		     int m=check();
		     if(m<minn)
		     {
		         ans.clear();
		         for(int i=0;i<len;++i) ans.push_back(num[i]);
		         minn=m;
		     }
		 }while(next_permutation(num.begin(),num.end()));
		return ans;
	}
};



第三题:

题意:给你最多C(1<=C<=4)种颜色的砖块,每种砖块有无限个(1*1*1的立方体),问用砖块拼成一个2*2*h(h<=H)的长方体,并且相邻两块单位立方体颜色相同的对数小于等于K的总方案数是多少。

题解:dp[h][i][j][k][l][x]表示高度h,最上面的面的四个立方体的颜色(i,j,k,l),总共的相邻的不同颜色对数为x。之后就是状态的递推了。

代码:

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;
#define LL long long
#define mod 1234567891
LL dp[55][5][5][5][5][10];//dp[h][i][j][k][l][x]表示高度h,最上面的面的四个立方体的颜色(i,j,k,l),总共的颜色对数为x
class TheBrickTowerHardDivTwo {
public:
	int find(int C, int K, int H) {
	    int temp;
		memset(dp,0,sizeof(dp));
		for(int i=0;i<C;++i)
		    for(int j=0;j<C;++j)
		        for(int k=0;k<C;++k)
		            for(int l=0;l<C;++l)
		            {
		                temp=((i==j)+(j==l)+(l==k)+(k==i));
		                if(temp<=K) dp[1][i][j][k][l][temp]=1;
		            }
		 for(int h=2;h<=H;++h)
		    for(int x=0;x<=K;++x)
		       	for(int i=0;i<C;++i)
		       	    for(int j=0;j<C;++j)
		       	        for(int k=0;k<C;++k)
		       	            for(int l=0;l<C;++l)
		       	                for(int a=0;a<C;++a)
		       	                    for(int b=0;b<C;++b)
		       	                        for(int c=0;c<C;++c)
		       	                             for(int d=0;d<C;++d)
		       	                             {
		       	                                  temp=((i==j)+(i==k)+(k==l)+(l==j)+(a==i)+(b==j)+(c==k)+(d==l));
		       	                                  if((dp[h-1][a][b][c][d][x])&&(x+temp<=K))
		       	                                      dp[h][i][j][k][l][x+temp]=(dp[h][i][j][k][l][x+temp]+dp[h-1][a][b][c][d][x])%mod;
		       	                             }
		   LL ans=0;
		   for(int h=1;h<=H;++h)
		       for(int x=0;x<=K;++x)
		       	   for(int i=0;i<C;++i)
		               for(int j=0;j<C;++j)
		                   for(int k=0;k<C;++k)
		                       for(int l=0;l<C;++l)
		                           ans=(ans+dp[h][i][j][k][l][x])%mod;
		  return (int)ans;
	}
};


来源:http://blog.csdn.net/acm_ted/article/details/7943977

你可能感兴趣的:(c,vector,Class,div,permutation)