1. 程式人生 > >2018年9月15日acm學習日誌

2018年9月15日acm學習日誌

2018.9.15 ACM-ICPC 2018 焦作賽區網路預賽

A.Magic Mirror(過)

簽到題,將輸入的字串轉換成大寫再與給定字串比較即可

B.Mathematical Curse(過)

題意:給定原始整數K,給定長為N的非零整數串,再給定M個計算符,求用完M個計算符後最大的結果

思路:

動態規劃

用兩個二維陣列g,h分別儲存當前最大和最小的結果,從前往後列舉整數和計算符;

狀態轉移方程為:g(i,j)=max(g(i,j),g(i-1,j-1)f(j)a(i),h(i-1,j-1)f(j)a(i))

                             h(i,j)=max(h(i,j),h(i-1,j-1)f(j)a(i),g(i-1,j-1)f(j)a(i))

初始條件為g(0,0)=h(0,0)=k                    答案為g(n,m)

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define INF 10000000000000000
using namespace std;
int n,m;
LL k,a[1005]={0};
LL g[1005][10],h[1005][10];
string s;
void Init()
{
	scanf("%d%d%lld",&n,&m,&k);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	cin>>s;
	s=" "+s;
}
LL Cal(LL a,char c,LL b)
{
	if(c=='+')return a+b;
	if(c=='-')return a-b;
	if(c=='*')return a*b;
	if(c=='/')return a/b;
}
LL Max(LL a,LL b)
{
	if(a>b)return a;
	return b;
}
LL Min(LL a,LL b)
{
	if(a<b)return a;
	return b;
}
void Solve()
{
	//初始化
	//memset(g,0,sizeof(g));
	//memset(h,0,sizeof(h));
	for(int i=0;i<=n;i++)
	for(int j=0;j<s.length();j++)
	{
		g[i][j]=-INF;
		h[i][j]=INF;
	}
	g[0][0]=h[0][0]=k;
	
	//動規
	int Len=s.length()-1;
	for(int i=1;i<=n;i++)
	for(int j=0;j<=Len;j++)
	{
		g[i][j]=-INF;
		h[i][j]=INF;
		if(j>i)continue;
		if(i>j)g[i][j]=g[i-1][j];
		if(j>0)
		{
			g[i][j]=Max(g[i][j],Cal(g[i-1][j-1],s[j],a[i]));
			g[i][j]=Max(g[i][j],Cal(h[i-1][j-1],s[j],a[i]));
		}
		
		h[i][j]=h[i-1][j];
		if(j>0)
		{
			h[i][j]=Min(h[i][j],Cal(h[i-1][j-1],s[j],a[i]));
			h[i][j]=Min(h[i][j],Cal(g[i-1][j-1],s[j],a[i]));
		}
		//printf("%d**%d**%lld**%lld\n",i,j,g[i][j],h[i][j]);
	}
	
	printf("%lld\n",g[n][Len]);
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		Init();
		Solve();
	}
	return 0;
}
/*
1
5 4 833
712 -543 347 -135 -33 
-/*+
*/

注意:1.最多五個運算子,每個數絕對值最大為1000,應取無限大為10^15 ++

2.陣列開大一點,不要抵著上限開

3.要注意合法狀態不能由多餘的非法狀態轉移得來

D.Sequence(未過)

題意:設長度為M,每個位置最大數為N的數串中每個數字最大的出現次數為x,求x的期望

F.Modular Production Line(未過)

題意:給出一定數目的區間,每個區間有個權值,求在覆蓋次數不超過k的情況下,總權和的最大值

思路:費用流