poj_3320_Jessica's Reading Problem poj_1159_Palindrome hdu_3001_travelling

poj_3320_Jessica's Reading Problem

http://poj.org/problem?id=3320

题意是给你一个序列,要求出一个最短的子序列的长度,子序列要求包括原序列的所有数字。

使用库函数里的map,把出现的第k种数字记为k。然后采用尺取法。l 和 r 记录左右区间,先 r ++,如果 l-1~r 之间符合要求,则记录结果,并且l++;

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define INF 999999999

int a[1000010];
int vis[1000010];

map<int ,int > my_map;

int main(){
	int n,cnt=1;
	scanf("%d",&n);
	for (int i=0;i<n;i++){
		scanf ("%d",&a[i]);
		if (my_map[a[i]]==0){
			my_map[a[i]]=cnt++;
		}
	}
	int count = 1, ans = n;
	vis[my_map[a[0]]]=1;
	for (int l=0, r=1; ; ){
		while ( count<cnt-1 && r<n ) {
			if (vis[my_map[a[r]]]==0){
				count++;
			}
			vis[my_map[a[r]]]++;
			r++;
		}
		if (count<cnt-1) break;
		if ( count == cnt -1 ) {
			ans=min(ans,r-l);
			if (vis[my_map[a[l]]] == 1 ) {
				count--;
			}
			vis[my_map[a[l]]]--;
			l++;
		}
	}
	printf ("%d\n",ans);

	return 0;
}

poj_1159_Palindrome

http://poj.org/problem?id=1159

给出一个长度为 n 的字符串,求出还需要插入几个字符使得字符串成为回文串。先求出最长回文子序列,剩下的就是要插入字符来使得字符串回文的了。另外,内存限制,用%2进行奇偶滚动(ps:n*n的short可以过)。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

short dp[5005][2];

int main(int argc, char const *argv[])
{
	//freopen ("in.txt","r",stdin);
	int n;
	char str[5005];
	memset(dp,0,sizeof(0));
	cin>>n>>str;
	dp[0][0]=1;
	for (int i = 1; i < n; ++i)
	{
		dp[i][i%2]=1;
		for (int j = i-1; j >= 0; --j)
		{
			if (str[i]==str[j]){
				dp[j][i%2]=dp[j+1][(i-1)%2]+2;
			}
			else
				dp[j][i%2]=max(dp[j+1][i%2],dp[j][(i-1)%2]);
		}
	}
	printf ("%hd\n",n-dp[0][(n-1)%2]);
	return 0;
}

hdu_3001_travelling

http://acm.hdu.edu.cn/showproblem.php?pid=3001

前几个礼拜开的这题,连样例都没法过,现在重开,终于各种残疾的过了。

有n个城市,m条道路,可以以任意一个城市作为起点,要求遍历所有的城市,并且每个城市不可以访问超过两次。

以每个城市的访问次数作为状态,就像TSP问题。

如果状态s的第u个城市访问过(两次或者一次),那他可以由状态s-u下的如果第v个城市被访问过+edge[v][s];

这里需要自己构建三进制。把n个城市的状态压缩。至于为什么不用枚举起点而是一次性把起点置为零,还有待脑残,(枚举了后TLE了)。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define INF 999999999

 int three (int n){
	int res=1;
	for (int i=0;i<n;i++){
		res*=3;
	}
	return res;
}

 int judge (int s,int u){
	int res=s;
	for (int i=0;i<u-1;i++){
		res/=3;
	}
	return res%3;
}

int dp[59049+3][12];

inline int min (int a,int b){//库的min会TLE ==
	if (a<b) return a;
	else return b;
}

int main(){//freopen("in.txt","r",stdin);cout<<"*"<<endl;
	int n, m;
	int map[12][12];
	int a,b,c;
	while (scanf ("%d%d",&n,&m)==2){
		for (int i=0;i<n;i++){
			for (int j=0;j<n;j++){
				map[i][j]=INF;
			}
		}
		for (int i=0;i<m;i++){
			scanf ("%d%d%d",&a,&b,&c);
			map[a-1][b-1]=map[b-1][a-1]=min(map[a-1][b-1],c);
		}
		int ans=INF,rec=INF;
		{//枚举起点 后来不用了。= =

			for (int s=0;s<three(n);s++){
				fill (dp[s],dp[s]+n,INF);
			}
			for (int st=0;st<n;st++){
				dp[three(st)][st]=0;
			}
			rec=INF;
			for (int s=0;s<three(n);s++){
				for (int k=0;k<n;k++){
					if (judge(s,k+1)!=0){
						for (int v=0;v<n;v++){
							if (judge(s,v+1)!=0){
								dp[s][k]=min(dp[s][k],dp[s-three(k)][v]+map[v][k]);
							}
						}
					}
				}
				int flag=1;
				for (int i=1;i<=n;i++){
					if(judge(s,i)==0){
						flag=0;
					}
				}
				if (flag==1){
					for (int j=0;j<n;j++){
						rec=min(rec,dp[s][j]);
					}
				}
			}
			ans=min(ans,rec);
		}
		if (ans==INF)printf ("-1\n");
		else printf ("%d\n",ans);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值