2016长乐夏令营Day2

T1:

反正要用sliding windows~,至于数字的处理

一开始用离散化,但是长乐的老爷机死都不让我过nlogn

最后Hash一发总算A了

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 1E6 + 10;
const int Hash = 67;
const int mo = 15000131;

int n,ans = 0,a[maxn],b[maxn],c[15000132];

int Lower_Bound(int l,int r,int x)
{
	if (l == r) return l;
	int mid = (l+r) >> 1;
	if (x <= a[mid]) return Lower_Bound(1,mid,x);
	else return Lower_Bound(mid+1,r,x);
}

int main()
{
	#ifdef DMC
	   freopen("DMC.txt","r",stdin);
	#else
	   freopen("snow.in","r",stdin);
	   freopen("snow.out","w",stdout);
	#endif
	
	/*for (int i = 2; i < maxn*15; i++)
		if (!pri[i]) 
			for (int j = i*2; j < maxn*15; j += i)
				pri[j] = 1;
	for (int i = maxn*15-1; i; i--)
		if (!pri[i]) {
			cout << i; return 0;
		}*/
	
	cin >> n;
	for (int i = 1; i <= n; i++) {
		scanf("%d",&a[i]);
		for (int j = 1; j <= 3; j++) {
			a[i] %= mo;
			a[i] *= Hash;
		}
		a[i] %= mo;
	}
	int i = 1;
	for (int j = 1; j <= n; j++) {
		if (!c[a[j]]) ++c[a[j]];
		else for (;;) {
			--c[a[i]]; ++i;
			if (!c[a[j]]) {++c[a[j]]; break;}
		}
		ans = max(ans,j-i+1);
	}
	cout << ans;
	return 0;
}


T2:

找个置换的规律,画画图就好了

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 110;

int n,ans,a[maxn];

void Work()
{
	for (;;) {
		if (a[1] == 1) return;
		swap(a[1],a[a[1]]);
		++ans;
	}
}

bool Judge()
{
	for (int i = 1; i <= n; i++)
		if (a[i] != i)
			return 0;
	return 1;
}

int main()
{
	#ifdef DMC
	   freopen("DMC.txt","r",stdin);
	#else
	   freopen("net.in","r",stdin);
	   freopen("net.out","w",stdout);
	#endif
	
	cin >> n;
	for (int i = 1; i <= n; i++) scanf("%d",&a[i]);
	for (;;) {
		if (Judge()) {cout << ans; return 0;}
		if (a[1] == 1) 
			for (int j = 2; j <= n; j++)
				if (a[j] != j) {
					swap(a[1],a[j]);
					++ans; break;
				}
		Work();
	}
	return 0;
}


T3:

加个虚拟节点,枚举不要的宠物,每次做一遍最小生成树

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 3E5 + 10;

struct E{
	int a,b,w;
	bool operator < (const E &B) const {
		return w < B.w;	
	}
}edgs[maxn],e[maxn];

int n,m,now,ans = ~0U>>1,tot,cnt,fa[300];

int fat(int x)
{
	return x == fa[x]?x:fa[x] = fat(fa[x]);
}

int main()
{
	#ifdef DMC
	   freopen("DMC.txt","r",stdin);
	#else
	   freopen("lovelygf.in","r",stdin);
	   freopen("lovelygf.out","w",stdout);
	#endif
	
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int z; scanf("%d",&z);
		edgs[++tot] = (E){0,i,z};
	}
	cin >> m;
	for (int i = 1; i <= m; i++) {
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		edgs[++tot] = (E){x,y,z};
	}
	for (int i = 1; i <= n; i++) {
		int sum; sum = now = cnt = 0;
		for (int j = 0; j <= n; j++) fa[j] = j;
		for (int j = 1; j <= tot; j++)
			if (edgs[j].a != i && edgs[j].b != i)
				e[++cnt] = edgs[j];
		sort(e + 1,e + cnt + 1);
		for (int j = 1; j <= cnt; j++) {
			int FA = fat(e[j].a);
			int FB = fat(e[j].b);
			if (FA != FB) {
				++sum;
				now += e[j].w;
				fa[FA] = FB;
			}
			if (sum == n - 1) break;
		}
		if (sum == n - 1) ans = min(ans,now);
	}
	cout << ans;
	return 0;
}

嗯。。虽然算出了e数组,但是写的时候写成edgs,作死


T4:

dp。。。多亏认识帅副

把原图看成RT三角形

每个点至少要学习其右上角的点和这个点往上所有点

f[i][j][k]:学习第i行第j列的技能,一共学了k个,最大威力

f[i][j][k] = max{f[x][j+1][l] + sum[i][j]}  (k = i+l,i-1<=x<=m)

最后,f[x][j+1][j]可以从下往上推的时候保留最大值

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 60;
typedef long long LL;

int n,m,tot,sa[60][60],sb[60][60];
LL a[60][60],f[51][51][501],ma[51][51][501],sum[51][51];

LL getLL()
{
	LL ret = 0;
	char ch = getchar();
	while (ch < '0' || '9' < ch) ch = getchar();
	while ('0' <= ch && ch <= '9')
		ret = ret*10LL + 1LL*(ch-'0'),ch = getchar();
	return ret;
}

int main()
{
	#ifdef DMC
	   freopen("DMC.txt","r",stdin);
	#else
	   freopen("skill.in","r",stdin);
	   freopen("skill.out","w",stdout);
	#endif
	
	cin >> n >> m;
	for (int i = 1; i <= n; i++) 
		for (int j = n-i+1; j; j--) 
			sa[i][j] = sa[i-1][j+1] + i;
			
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n-i+1; j++)
			a[i][j] = getLL(),sum[i][j] = a[i][j] + sum[i-1][j];
			
	for (int i = n; i; i--) {
		for (int j = n-i+1; j > 0; j--) {
			for (int l = sa[j-1][i+1]; l <= m; l++)
				if (j + l <= m)
					f[j][i][j+l] = sum[j][i] + ma[j-1][i+1][l];
				else break;
			for (int l = sa[j][i]; l <= m; l++)
				ma[j][i][l] = max(f[j][i][l],ma[j+1][i][l]);
		}
		for (int l = 0; l <= m; l++) {
			f[0][i][l] = ma[0][i+1][l];
			ma[0][i][l] = max(f[0][i][l],ma[1][i][l]);
		}
			
	}
	LL ans = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n-i+1; j++)
			ans = max(ans,f[i][j][m]);
	cout << ans;
	return 0;
}

写的时候漏判行数为0的边界。。。GGGG


你可能感兴趣的:(dp,hash,2016长乐夏令营,模拟,最小生成树)