第一题:
题意:有两种颜色的砖块,红色和蓝色。给你两种砖块的高度和数量,要求砖块只能放在与其不同颜色的砖块上面。问一共可以叠出多少种高度。
题解:暴力枚举。
代码:
#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