SRM 497 DIV1 550

题意:给出一颗树(也有可能是多棵树,那就每棵树分别计算后求和,需要自己先构造),书上的节点有颜色和tag两种信息。颜色共有7种,tag有3种,分别是“u”,“i” ,“b”类型的tag。我们要对这棵树进行染色,每次染色,可以对当前节点染色,也可以对其子树染色。对子树染色时,每次染色能且仅能将所有类型某一tag的节点染成某一相同颜色。问至少需要染色多少次,才能将每个节点染成其所需的相应颜色。

解题思路:我们要得到的答案为某一最优解,因此能够想到用dp做,树上的dp自然就是树形dp了。dp[id][i][j][k]表示将id节点染成其所需的颜色,将其子树中tag类型为u的节点染成 i 颜色,将其子树中tag类型为i的节点染成 j 颜色,将其子树中tag类型为b的节点染成k颜色,至少需要几次。

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <sstream>
#include <queue>
#include <string>
#include <deque>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
template <class T> void checkmax(T &t, T x) { if (x > t) t = x; }
template <class T> void checkmin(T &t, T x) { if (x < t) t = x; }
template <class T> void _checkmax(T &t, T x) { if (t == -1 || x > t) t = x; }
template <class T> void _checkmin(T &t, T x) { if (t == -1 || x < t) t = x; }
typedef long long ll;
struct Edge
{
	int t , next ;
} edge[111111] ;
int head[111] , tot ;
class CssRules {
public:
	int col[111] , tag[111] , du[111] ;
	int min ( int a , int b ) { return a < b ? a : b ; }
	void new_edge ( int a , int b )
	{
		edge[tot].t = b ;
		edge[tot].next = head[a] ;
		head[a] = tot ++ ;
	}

	int dp[111][10][10][10] ;

	void init ()
	{
		tot = 0 ;
		memset ( head , -1 , sizeof ( head ) ) ;
		int i , j , k , l ;
		memset ( du , 0 , sizeof ( du ) ) ;
		memset ( dp , -1 , sizeof ( dp ) ) ;
	}

	int dfs ( int id , int u , int I , int b )
	{
		if ( head[id] == -1 )
		{
			if ( tag[id] == 1 ) return u != col[id] ;
			if ( tag[id] == 2 ) return I != col[id] ;
			if ( tag[id] == 3 ) return b != col[id] ;
		}
		if ( dp[id][u][I][b] != -1 ) return dp[id][u][I][b] ;
		int i , j , k , l , ret = 0 , add = 111111111 ;
		if ( tag[id] == 1 ) ret = ( u != col[id] ) ;
		if ( tag[id] == 2 ) ret = ( I != col[id] ) ;
		if ( tag[id] == 3 ) ret = ( b != col[id] ) ;
		for ( i = 0 ; i < 8 ; i ++ )
			for ( j = 0 ; j < 8 ; j ++ )
				for ( k = 0 ; k < 8 ; k ++ )
				{
					if ( ( u && !i ) || ( I && !j ) || ( b && !k ) ) continue ;
					int cnt = (u!=i) + (I!=j) + (b!=k) ;
					for ( l = head[id] ; l != -1 ; l = edge[l].next )
						cnt += dfs ( edge[l].t , i , j , k ) ;
					add = min ( cnt , add ) ;
				}
				return dp[id][u][I][b] = ret + add ;
	}
	int getMinimalCssRuleCount(vector <string> xthml)  {
    	string s ;
		init () ;
		int k = xthml.size () , i , j , l , m ;
		s = "" ;
		int last[1000] , top = 0 ;
		for ( i = 0 ; i < k ; i ++ )
			s += xthml[i] ;
		k = s.size () ;
		int id = 0 ;
		for ( i = 0 ; i < k ; i ++ )
		{
			if ( s[i] == '<' && s[i+1] != '/' )
			{
				id ++ ;
				if ( top != 0 )
					new_edge ( last[top] , id ) , du[id] ++ ;
				last[++top] = id ;
				if ( s[i+1] == 'u' ) tag[id] = 1 ;
				if ( s[i+1] == 'i' ) tag[id] = 2 ;
				if ( s[i+1] == 'b' ) tag[id] = 3 ;
			}
			else if ( s[i] == '<' && s[i+1] == '/' ) top -- ;
			else if ( s[i] == ':' )
			{
				if ( s[i+1] == 'r' ) col[id] = 1 ;
				else if ( s[i+1] == 'w' ) col[id] = 2 ;
				else if ( s[i+1] == 'y' ) col[id] = 3 ;
				else if ( s[i+1] == 'b' && s[i+3] == 'a' ) col[id] = 4 ;
				else if ( s[i+1] == 'b' && s[i+3] == 'u' ) col[id] = 5 ;
				else if ( s[i+1] == 'g' && s[i+3] == 'a' ) col[id] = 6 ;
				else col[id] = 7 ;
			}
		}
		int ans = 0 ;
		for ( i = 1 ; i <= id ; i ++ )
			if ( du[i] == 0 )
			{
				int mx = 111111111 ;
				for ( j = 0 ; j < 8 ; j ++ )
					for ( k = 0 ; k < 8 ; k ++ )
						for ( l = 0 ; l < 8 ; l ++ )
						{
							int add = ( l != 0 ) + ( j != 0 ) + ( k != 0 ) + 1 ;
							for ( m = head[i] ; m != -1 ; m = edge[m].next )
								add += dfs ( edge[m].t , j , k , l ) ;
							mx = min ( mx , add ) ;
						}
				ans += mx ;
			}
		return ans ;
	}

	// BEGIN CUT HERE
public:
	void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }
private:
	template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
	void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
	void test_case_0() { string Arr0[] = {"<b id='x' style='color:red'></b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(0, Arg1, getMinimalCssRuleCount(Arg0)); }
	void test_case_1() { string Arr0[] = {"<b id='x' style='color:red'>","<b id='y' style='color:red'>",
		"<b id='z' style='color:red'>","</b></b></b>"}
	; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(1, Arg1, getMinimalCssRuleCount(Arg0)); }
	void test_case_2() { string Arr0[] = {"<b id='x' style='color:red'>",
		"<b id='y' style='color:red'>",
		"<b id='w' style='color:red'>",
		"</b>",
		"</b>",
		"<u id='z' style='color:red'>",
		"</u>",
		"</b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; verify_case(2, Arg1, getMinimalCssRuleCount(Arg0)); }
	void test_case_3() { string Arr0[] = {"<b id='x' style='color:red'>",
		"<i id='y' style='color:black'>",
		"<u id='w' style='color:white'>",
		"</u>",
		"</i>",
		"<u id='z' style='color:yellow'>",
		"</u>",
		"</b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; verify_case(3, Arg1, getMinimalCssRuleCount(Arg0)); }
	void test_case_4() { string Arr0[] = {"<b id='x' style='col", "or:red'></b>", "<b id=", "'xx' style='color", ":red'></b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(4, Arg1, getMinimalCssRuleCount(Arg0)); }

	// END CUT HERE

};

// BEGIN CUT HERE
int main() {
	CssRules ___test;
	___test.run_test(-1);
}
// END CUT HERE


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值