动态规划


poj1163

#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 105

int n;
int num[MAXN][MAXN];
int d[MAXN];

int max(int a,int b)
{
	if(a<b)
		return b;
	else
		return a;
}

int main(){
	scanf("%d",&n);
	
	
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
			scanf("%d",&num[i][j]);
	}
	
	for(int i=1;i<=n;i++)
		d[i]=num[n][i];
	
	
	for(int i=n-1;i>=1;i--)
	{
		for(int j=1;j<=i;j++)
		{
			d[j]=max(d[j],d[j+1])+num[i][j];
		}
	}
	
	printf("%d",d[1]);
}


百练2757

#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 1005

int n;
int num[MAXN];
int d[MAXN];

int max(int a, int b) {
	if (a<b)
		return b;
	else
		return a;
}

int main() {
	scanf("%d", &n);



	for (int i = 0; i<n; i++) {
		scanf("%d", &num[i]);
		d[i]=1;
	}



	for (int i = 1; i<n; i++) {
		for (int j = 0; j<i; j++) {
			if (num[i]>num[j]) {
				d[i] = max(d[i], d[j] + 1);
			}
		}
	}

	int max_d = d[0];

	for (int i = 1; i<n; i++) {
		if (d[i]>max_d)
			max_d = d[i];
	}

	printf("%d", max_d);

}

poj1458

#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 1005
using namespace std;

char x[MAXN];
char y[MAXN];
int d[MAXN][MAXN];



int main() {
	while (cin >> x >> y){
		
		

		int len1 = strlen(x);
		int len2 = strlen(y);
		
		for(int i=1;i<=len1;i++)
		{
			d[i][0]=0;
		}
		for(int i=1;i<=len2;i++)
		{
			d[0][i]=0;
		}
		
		
		for (int i = 1; i<=len1; i++) {
			for (int j = 1; j<=len2; j++) {
				if (x[i-1] == y[j-1]) {
					d[i][j] = d[i - 1][j - 1] + 1;
				}
				else
					d[i][j] = max(d[i][j - 1], d[i - 1][j]);
			}
		}
		printf("%d\n", d[len1 ][len2 ]);
	}
	 

		
}




POJ3624

#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 3450
using namespace std;



int m;
int n;
int w[MAXN];
int d[MAXN];
int dp[12885];

int main() {
	scanf("%d%d", &n, &m);


	for (int i = 1; i <= n; i++)
		scanf("%d%d", &w[i], &d[i]);


	memset(dp, 0, sizeof(dp));


	for (int j = m; j >= w[1]; j--) {
		dp[j]=d[1];
	}

	for (int i = 2; i <= n; i++) {
		int j;
		for (j = m; j >= w[i]; j--) {//вЊга
			dp[j] = max(dp[j], dp[j - w[i]] + d[i]);
		}
	}
	printf("%d\n", dp[m]);
}



简单整数划分

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 51


int num;

long long f[MAXN][MAXN];


long long fun(int n, int m) {
	if (f[n][m] != -1)
		return f[n][m];
	if (m == 1 || n == 1)
		return 1;
	else if (n == m)
		return f[n][m]=(1 + fun(n, m - 1));
	else if (n > m)
		return f[n][m] = (fun(n - m, m) + fun(n, m - 1));
	else
		return f[n][m]= fun(n, n);
}


int main() {
	while (scanf("%d", &num) == 1) {
		memset(f, -1, sizeof(f));

		printf("%lld\n", fun(num, num));
	}
	


}

百练1088

#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

#define MAXN 105

struct Node {
	int r;
	int c;
	int h;
	Node(int rr, int cc, int hh) :r(rr), c(cc), h(hh) {}

};

bool operator<(const Node &n1, const Node & n2) {
	return n1.h>n2.h;
}

int len[MAXN][MAXN];
int num[MAXN][MAXN];
int r, c;


int main() {
	scanf("%d%d", &r, &c);

	priority_queue<Node> h;
	memset(len,0,sizeof(0));

	int i, j;
	for (i = 1; i <= r; i++) {
		for (j = 1; j <= c; j++) {
			scanf("%d", &num[i][j]);
			h.push(Node(i, j, num[i][j]));
		}
	}

	while (!h.empty()) {
		Node n = h.top();
		h.pop();
		int rr = n.r;
		int cc = n.c;
		int hh = n.h;
		
		len[rr][cc]=1;

		if (rr>1 && num[rr][cc] >num[rr - 1][cc])
			len[rr][cc] = max(len[rr][cc], len[rr - 1][cc]+1);
		
		if (rr<r && num[rr][cc] >num[rr + 1][cc])
			len[rr][cc] = max(len[rr][cc], len[rr + 1][cc]+1);
		
		if (cc<c && num[rr][cc] >num[rr][cc + 1])
			len[rr][cc] = max(len[rr][cc], len[rr][cc + 1]+1);
		
		if (cc>1 && num[rr][cc] >num[rr][cc - 1])
			len[rr][cc] = max(len[rr][cc], len[rr][cc - 1]+1);
	}

	int ans = 0;

	for (i = 1; i <= r; i++) {
		for (j = 1; j <= c; j++) {
			if (ans<len[i][j])
				ans = len[i][j];
		}
	}
	printf("%d", ans);

}




复杂整数划分

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 55

int n, k;
int dp[MAXN][MAXN];
int dp1[MAXN][MAXN];
//int da[MAXN][MAXN];//第几个数;多少个数
//int db[MAXN][MAXN];
//int f[MAXN][MAXN];
//int g[MAXN][MAXN];
int(&da)[MAXN][MAXN] = dp;
int(&db)[MAXN][MAXN] = dp;
int(&f)[MAXN][MAXN] = dp;
int(&g)[MAXN][MAXN] = dp1;

int fun2(int i, int j) {
	if (db[i][j] != -1)
		return db[i][j];
	if (i == 1)
		return db[i][j] = 1;
	if (j == 1)
		return db[i][j] = 0;
	if (i < j)
		return db[i][j] = fun2(i, i);
	else if (i == j)
		return db[i][j] = 1 + fun2(i, j - 1);
	else
		return db[i][j] = fun2(i - j, j - 1) + fun2(i, j - 1);//有点难
}


int main() {
	while (scanf("%d%d", &n, &k) == 2) {


		memset(da, 0, sizeof(da));
		da[1][1] = 1;
		for (int i = 2; i <= n; i++) {
			for (int j = 1; j <= i; j++) {
				if (j == 1)
					da[i][j] = 1;
				else
					da[i][j] = da[i - j][j] + da[i - 1][j - 1];
			}
		}
		printf("%d\n", da[n][k]);


		memset(db, -1, sizeof(db));

		printf("%d\n", fun2(n, n));

		memset(f, 0, sizeof(f));
		memset(g, 0, sizeof(g));
		
		f[1][1] = 1;
		g[1][1] = 0;
		for (int i = 2; i <= n; i++) {
			for (int j = 1; j <= i; j++) {
				f[i][j] = f[i - 1][j - 1] + g[i - j][j];
				g[i][j] = f[i - j][j];
			}
		}
		int sum = 0;
		for (int j = 1; j <= n; j++)
			sum += f[n][j];

		printf("%d\n", sum);
	}

}



最佳加法表达式

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define MAXN 55

#define INFINITY1 1<<30

int dp[MAXN][MAXN];//前i个数字加上+号形成的,多少个+号

int n, m;
char str[MAXN];
int num[MAXN];

int toInt(int a, int b)
{
	int sum = 0;
	for (int i = a, j = (int)pow(10, (b - a)); i <= b; i++, j /= 10)
		sum += num[i] * j;
	return sum;
}


int main()
{
	scanf("%s", str);
	scanf("%d", &m);
	n = strlen(str);

	if (m == 0)
		printf("%d", toInt(1, n));
	else if (m >= n)
		printf("no");
	else
	{
		for (int i = 0; i<n; i++)
			num[i + 1] = int(str[i] - '0');


		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
				dp[i][j] = INFINITY1;
			}
		}

		for (int i = 1; i <= n; i++)
		{
			dp[i][0] = toInt(1, i);
		}

		for (int i = 2; i <= n; i++)
		{
			for (int j = 1; j<i; j++)
			{
				for (int k = j+1; k <= i; k++)
				{
					dp[i][j] = min(dp[k - 1][j - 1] + toInt(k, i), dp[i][j]);
				}
				
			}
		}


		printf("%d", dp[n][m]);
	}


}



百练2755神奇的口袋

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define MAXN 25
#define MAXW 45


int dp[MAXN][MAXW];//前i个,形成j质量
int a[MAXN];
int n;

int main(){
	scanf("%d",&n);
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		dp[i][0]=1;
	}
	
	dp[0][0]=1;
	
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=40;j++)
		{
			if(a[i]<=j)
				dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
			else
				dp[i][j]=dp[i-1][j];
		}
	}
	
	printf("%d",dp[n][40]);
}




栅栏poj1037

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define MAXN 25
#define DOWN 0
#define UP 1


int k;
int n;
long long c;

long long dp[MAXN][MAXN][2];

void initDp()
{
	memset(dp, 0, sizeof(dp));

	dp[1][1][UP] = dp[1][1][DOWN] = 1;

	for (int i = 2; i <= n; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			for (int k = 1; k <= j - 1; k++)
				dp[i][j][DOWN] += dp[i - 1][k][UP];
			for (int k = j; k <= i - 1; k++)
				dp[i][j][UP] += dp[i - 1][k][DOWN];
		}
	}
}

void print()
{
	int ans[MAXN];
	int used[MAXN];
	memset(used, 0, sizeof(used));
	for (int i = 1; i <= n; i++)
	{
		int no = 0;

		long long skip = 0;
		int j;
		for (j = 1; j <= n; j++)
		{
			//don't be afraid
			if (!used[j])
			{
				no++;
				if (i == 1)
				{
					skip = dp[n][no][DOWN] + dp[n][no][UP];
				}
				else if (ans[i - 1]<j && (i <= 2 || ans[i - 2]>ans[i - 1]))
				{
					skip = dp[n-i+1][no][DOWN];
				}
				else if (ans[i - 1]>j && (i <= 2 || ans[i - 2]<ans[i - 1]))
				{
					skip = dp[n-i+1][no][UP];
				}
				if (skip >= c)
				{
					break;
				}
				else
				{
					c -= skip;
				}
				
			}

		}
		used[j] = 1;
		ans[i] = j;
	}
	for (int i = 1; i <= n; i++)
		printf("%d ", ans[i]);
	printf("\n");
}



int main()
{
	scanf("%d", &k);



	while (k--)
	{
		scanf("%d%lld", &n, &c);
		initDp();
		print();
	}



}




格子poj1390

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define MAXN 205

int len[MAXN];
int color[MAXN];
int clickBox[MAXN][MAXN][MAXN];
int n;


int fun(int i, int j, int extraLen)
{
	if (clickBox[i][j][extraLen] != -1)
		return clickBox[i][j][extraLen];
	if (j == i)
		return  clickBox[i][j][extraLen] = (len[i] + extraLen)*(len[i] + extraLen);
	if (j<i)
		return 0;

	clickBox[i][j][extraLen] = fun(i, j - 1, 0) + (len[j] + extraLen)*(len[j] + extraLen);

	for (int k = i; k<j; k++)
	{
		if (color[k] == color[j])
		{
			clickBox[i][j][extraLen] = max(clickBox[i][j][extraLen], fun(k + 1, j - 1, 0) + fun(i, k, len[j] + extraLen));
		}
	}
	return clickBox[i][j][extraLen];
}

int main()
{
	int t;
	scanf("%d", &t);
	int times;
	for (times = 0; times<t; times++)
	{
		int n1;
		memset(clickBox, -1, sizeof(clickBox));
		scanf("%d", &n1);
		int lastColor = 0, lenCnt = 1;
		int colorNow;
		int colorCnt = 1;
		scanf("%d", &colorNow);
		lastColor = colorNow;

		for (int i = 2; i <= n1; i++)
		{
			scanf("%d", &colorNow);


			if (lastColor == colorNow)
			{
				lenCnt++;
			}
			else
			{
				color[colorCnt] = lastColor;
				len[colorCnt] = lenCnt;
				colorCnt++;
				lenCnt = 1;
				lastColor = colorNow;
			}

		}
		color[colorCnt] = lastColor;
		len[colorCnt] = lenCnt;
		n = colorCnt;
		printf("Case %d: %d\n", times + 1, fun(1, n, 0));
	}



}





炮兵阵兵poj1185

#include<stdio.h>
#include<string.h>
#include<algorithm>

#define MAXCONDITION 65
#define MAXN 105
#define MAXM 15
using namespace std;

int N,M;
char inputChar[MAXN][MAXM];
int land[MAXN];

int conditionCnt=0;
int condition[MAXCONDITION];
int conditionOneNum[MAXCONDITION];

int dp[MAXN][MAXCONDITION][MAXCONDITION];

int getOne(int num)
{	
	int ret=0;
	for(int i=0;i<M;i++)
	{
		if(num & 1<<i)
			ret++;
	}
	return ret;
}

void initCondition(){
	for(int i=0;i< 1<<M;i++)
	{
		if( !(i & (i<<1)) && !(i & (i<<2)) )
		{
			condition[conditionCnt]=i;
			conditionOneNum[conditionCnt]=getOne(i);
			conditionCnt++;
		}
			
	}
}

int isLegal2Condition(int i,int j)
{
	return !(condition[i]&condition[j]);
}

int isLegalConditionLand(int c,int l)
{
	return !(condition[c] & (~land[l]));
}


int main()
{
	memset(conditionOneNum,0,sizeof(conditionOneNum));
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++)
	{
		scanf("%s",inputChar[i]);
		for(int j=0;j<M;j++)
		{
			if(inputChar[i][j]=='P')//平原
			{
				land[i] = ((1<<(M-1-j)) | land[i]);
			}
		}
	}
	
	initCondition();
	
	memset(dp,-1,sizeof(dp));
	
	for(int j=0;j<conditionCnt;j++)
	{
		if(!isLegalConditionLand(j,0))
			continue;
		for(int k=0;k<conditionCnt;k++)
		{
				dp[0][j][k]=conditionOneNum[j];
		}
	}
	
	
	
	for(int i=1;i<N;i++)
	{
		for(int j=0;j<conditionCnt;j++)
		{
			if(!isLegalConditionLand(j,i))
				continue;
			
			for(int k=0;k<conditionCnt;k++)
			{
				if(!isLegal2Condition(j,k))
					continue;
				for(int m=0;m<conditionCnt;m++)
				{
					if(!isLegal2Condition(j,m))
						continue;
					if(dp[i-1][k][m]==-1)
						continue;
					dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][m]+conditionOneNum[j]);
				}
			}
		}
	}
	
	
	int ans=0;
	
	
		for(int j=0;j<conditionCnt;j++)
		{
			for(int k=0;k<conditionCnt;k++)
			{
				if(ans<dp[N-1][j][k])
				{
					ans=dp[N-1][j][k];
				}
				
			}
		}
	
	printf("%d",ans);
	
	
	
}


切割回文

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 1010
#define INFINITE 1<<30

char str[MAXN];

int dp[MAXN];


int isHuiWen(int i,int j)
{
	
	int cha=j-i;
	if(cha%2==0)
		cha-=1;
	
	for(int off=0;off<cha;off++)
	{
		if(str[i+off]!=str[j-off])
			return 0;
	}
	return 1;
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%s",str);
		int len=strlen(str);
		
		for(int i=0;i<len;i++)
			dp[i]=INFINITE;
		
		dp[0]=0;
		
		for(int i=1;i<len;i++)
		{
			dp[i]=dp[i-1]+1;
			if(isHuiWen(0,i))
				dp[i]=0;
			
			for(int j=1;j<i;j++)
			{
				
				if(isHuiWen(j,i))
				{
					dp[i]=min(dp[i],dp[j-1]+1);
				}
			}
		}
		printf("%d\n",dp[len-1]);
	}
}



股票买卖

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 100010
#define MAXTIME 3
#define INFINITE 1<<30
int N;
int num[MAXN];
int dp[MAXN][MAXTIME];


int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &N);
		for (int i = 1; i <= N; i++)
		{
			scanf("%d", &num[i]);
		}
		memset(dp, 0, sizeof(dp));

		int maxAdd;


		for (int k = 1; k <= 2; k++)
		{
			maxAdd = -INFINITE;
			for (int i = 2; i <= N; i++)
			{
				maxAdd = max(maxAdd, dp[i - 1][k - 1] - num[i - 1]);

				dp[i][k] = max(dp[i - 1][k], maxAdd + num[i]);
			}
		}

		printf("%d\n", dp[N][2]);

	}

}



奶牛poj2373

#include<iostream>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;

#define MAXN 1000009
#define MAXNCOW 1005
#define INFINITE 1<<30
int n, l;
int a, b;
int f[MAXN];
int cowThere[MAXN];

struct Fx
{
	int f;
	int x;
	Fx(int ff, int xx) :f(ff), x(xx)
	{
	}

};

bool operator<(const Fx & a, const Fx & b)
{
	return a.f>b.f;
}

priority_queue<Fx> fxq;

int main()
{
	scanf("%d%d", &n, &l);
	scanf("%d%d", &a, &b);
	a = a << 1;
	b = b << 1;
	int s, e;
	for (int i = 0; i<n; i++)
	{
		scanf("%d%d", &s, &e);
		cowThere[s + 1]++;
		cowThere[e]--;
	}
	int sum = 0;
	for (int i = 0; i <= l; i++)
	{
		f[i] = INFINITE;
		sum += cowThere[i];
		cowThere[i] = sum>0;
	}


	for (int i = a; i <= b; i += 2)
	{
		if (cowThere[i] == 0)
		{
			f[i] = 1;
			if (i <= b + 2 - a)
				fxq.push(Fx(1, i));
		}

	}



	int x;
	for (x = b + 2; x <= l; x += 2)
	{
		

		if (!cowThere[x])
		{

			while (!fxq.empty())
			{
				Fx node = fxq.top();

				if (node.x < x - b)
					fxq.pop();
				else
				{
					f[x] = node.f + 1;
					break;
				}
			}
		}
		if (f[x + 2 - a] != INFINITE)
		{
			fxq.push(Fx(f[x + 2 - a], x + 2 - a));
		}
	}

	if (f[l] == INFINITE)
		printf("-1");
	else
		printf("%d", f[l]);

}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值