ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UVa 1630 - Folding (区间dp)

2021-07-30 16:32:55  阅读:210  来源: 互联网

标签:1630 ch Folding string int memset maxn UVa dp


题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4505

没有看出这是一道区间 \(dp\)

可以将串 \(S\) 分成 \(AB\) 两部分,一种方案是对 \(AB\) 直接拼接,另一种方案是将 \(B\) 折叠进入 \(A\),按照这两种方案转移即可,记录一下转移点用来输出方案

有一些关于字符串 \(string\) 的操作,详见代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 105;
const int INF = 0x3f3f3f3f;

int n;
int dp[maxn][maxn], g[maxn][maxn];
string s; 

bool check(int i, int j, int k){
	if((j-k) % (k-i+1) != 0) return false;
	int mul = (j-k)/(k-i+1);
	string t = s.substr(i-1, k-i+1); // 位置从 0 开始 
	string r = s.substr(k, j-k);
	string l;
	for(int p = 1 ; p <= mul ; ++p) l += t; 
	if(l == r) return true;
	else return false;
}

int count(int x){
	int tmp = x;
	int cnt = 0;
	while(tmp){
		++cnt;
		tmp /= 10;
	}
	return cnt;
}

void print(int i, int j){
	if(i == j){
		cout << s.substr(i-1, 1);
		return;
	}
	
	if(g[i][j] < 0){
		print(i, -g[i][j]);
		print(-g[i][j]+1, j); 
	} else{
		int k = g[i][j];
		int mul = (j-k)/(k-i+1); ++mul;
		cout << mul << '(';
		print(i, k); 
		cout << ')';
	}
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	while(cin >> s){
		memset(dp, 0x3f, sizeof(dp));
		memset(g, 0x3f, sizeof(g));
		
		n = s.length();
		
		for(int i = 1 ; i <= n ; ++i) dp[i][i] = 1;
		
		for(int l = 2 ; l <= n ; ++l){
			for(int i = 1 ; i + l - 1 <= n ; ++i){
				int j = i + l - 1;
				for(int k = i ; k < j ; ++k){
					if(dp[i][k] + dp[k+1][j] < dp[i][j]){
						dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]); // 直接拼 	
						g[i][j] = -k;					
					}

					// 折叠
					if(check(i, j, k)){
						int mul = (j-k)/(k-i+1); mul += 1;
						
						if(count(mul) + 2 + dp[i][k] < dp[i][j]){
							dp[i][j] = min(dp[i][j], count(mul) + 2 + dp[i][k]);				
							g[i][j] = k;
						}
					}
				}
			} 
		}
		
		print(1, n); cout << endl;
	}
	return 0;
}

标签:1630,ch,Folding,string,int,memset,maxn,UVa,dp
来源: https://www.cnblogs.com/tuchen/p/15080248.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有