20200912 day7 刷题记录

1 1040 平面分割

题面

平面内有(n)条直线,其中(p)条相交于同一点,则这些直线最多能把平面分隔成多少个不同的部分?
(nleq 500,pgeq 2)

题解

贪心。开始我们有p个直线构成一个菊花图,分出2 p个区域,然后我们每加一条直线,他都能构造出一种于其他x条直线都有交点的画法,会将x+1个区域分出新的一半,所以我们可以举个例子,比如样例 12 5
说白了就是开始5条线构成菊花图,再向上插7条 于是 73 = 10 + 6 + 7 + 8 + 9 + 10 +11 + 12 然后推广到普遍情况等差数列瞎算一下就行了

未AC原因

递推没有推出来

代码

#include <cstdio>
int main(){
      int a,b;
      scanf("%d%d",&a,&b);
      printf("%d
",2 * b + (b + a + 1) * (a - b) / 2);
      return 0;
} 

POJ1458 最长公共子序列

给出两个字符串,求出这样的一个最长的公共子序列的长度:子序列中的每个字符都能在两个原串中找到,而且每个字符的先后顺序和原串中的先后顺序一致。

题解

两个字符串我分别设为(a,b),他们的长度分别为(n,m),设(f[i][j])表示(a)串的(1)$i$,$b$串的1j的LCS为多少。如果(a[i]=b[j])的话,(f[i][j]=f[i-1][j-1]+1);否则(f[i][j]=max(f[i-1][j],f[i][j-1])) //这条的正确性很显然
复杂度为(O(nm))

诶我式子写错了吗?

f[i][j]=max(f[i-1][j-1],max(f[i-1][j],f[i][j-1]) )

我猜你们认为这才对。事实上这个确实对,但我之前写的也对。为什么?
实际上,(f[i-1][j])或者(f[i][j-1])(f[i-1][j-1])相比,要么相等,要么比它大1(以前者为例,比如说第(i-1)(j)匹配上了,就有可能存在比它大取得情况)
所以完全没问题。

2 1097 0/1 背包

未AC原因

dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])||j-w[i]>=0
第二个是dp[i-1]!!!!

代码

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int value[35],weight[35];
int n,m;
int dp[35][205];
int main(){
	scanf("%d %d",&m,&n);
	for(int i=1;i<=n;i++){
		scanf("%d %d",&weight[i],&value[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(j-weight[i]>=0) 
			dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
			else dp[i][j]=dp[i-1][j];
		}
	}
	printf("%d",dp[n][m]);
	return 0;
}
要做就做南波万
原文地址:https://www.cnblogs.com/liuziwen0224/p/20200912day7-002.html