BestCode比赛里有汉语的题意, 并且每道题都有官方的题解,这里都不在描述了
这道题就是让求改一个数组元素之后的数组的最大连续和, 求最大的连续和的是O(n)的复杂度, 然后我们可以枚举改变每一个元素再求最大连续和;复杂度为O(n^2).
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1000 + 10;
#define LL long long
const LL inf = 0x3f3f3f3f;
LL s[maxn];
LL solve(int n)
{
LL ans = -inf;
LL sum = 0;
for(int i = 0; i < n; i++)
{
sum += s[i];
ans = max(ans, sum);
if(sum < 0)
sum = 0;
}
return ans;
}
int main()
{
int T, n;
LL p;
scanf("%d", &T);
while(T--)
{
scanf("%d%I64d", &n, &p);
for(int i = 0; i < n; i++)
scanf("%I64d", &s[i]);
LL ans = -inf;
for(int i = 0; i < n; i++)
{
LL t = s[i];
s[i] = p;
ans = max(ans, solve(n));
s[i] = t;
}
printf("%I64d\n", ans);
}
return 0;
}
这道题在比赛时候没做出来,主要在想怎么打怪兽最优,一直没想出来; 其实我们可以整体考虑。到最后一定是最强的k把枪消灭了最弱的k个怪兽。 我们先排序,在求出最多能用几把枪。 然后再枚举用几把枪得分最高就好。 为了降低复杂度我们先用前缀和数组分别保存枪和怪兽的能力值,最后直接就能取值了。 总得时间复杂度为O(nlogn).
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 100005;
const LL inf = 0x3f3f3f3f;
LL a[maxn], b[maxn], sua[maxn], sub[maxn];
int main()
{
int T, n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
sua[0] = sub[0] = 0;
for(int i = 1; i <= n; i++)
scanf("%I64d", &a[i]);
for(int i = 1; i <= m; i++)
scanf("%I64d", &b[i]);
sort(a+1, a+n+1);
sort(b+1, b+m+1);
int cnt = 0;
for(int i = 1; i <= n; i++)
if(a[i] < b[1])
sua[i] = 0, cnt = i;
else
sua[i] = sua[i-1] + a[i];
for(int i = 1; i <= m; i++)
sub[i] = sub[i-1] + b[i];
int k = min(n-cnt, m);
LL ans = -inf;
for(int i = 1; i <= k; i++)
{
LL t = sua[n]-sua[n-i]-sub[i];
ans = max(ans, t);
}
printf("%I64d\n", ans);
}
return 0;
}
两次dp题, 比赛不会做的。
dp[i][j] 表示 X 串的前i个字符和 Y 串的前j个字符的最长公共子序列的长度,在这个基础上我们再进行一个动态规划。用 f[i][j] 表示在 X 串的前i个字符中,有多少个长度为 dp[i][j] 的子序列在 Y 的前j个字符中也出现了。转移:若 dp[i−1][j]==dp[i][j] ,则 f[i][j]+=f[i−1][j] ,表示i这个字符不选;再考虑选i这个字符,找到 Y 串前j个字符中最靠后的与X[i]匹配的字符的位置,设为 p ,若 dp[i−1][p−1]+1==dp[i][j] ,则 f[i][j]+=f[i−1][p−1] 。最终的答案即为 f[n][m] 。复杂度 O(n2) 。#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define LL long long const int maxn = 1005; const int mod = 1000000007; char x[maxn], y[maxn]; int dp[maxn][maxn], p[maxn][maxn]; LL f[maxn][maxn]; void inin() { scanf("%s%s", x+1, y+1); memset(dp, 0, sizeof(dp)); memset(p, 0, sizeof(p)); int lenx = strlen(x+1); int leny = strlen(y+1); for(int i = 1; i <= lenx; i++) { for(int j = 1; j <= leny; j++) if(x[i] == y[j]) dp[i][j] = dp[i-1][j-1] + 1; else dp[i][j] = max(dp[i-1][j], dp[i][j-1]); } for(int i = 1; i <= lenx; i++) { int t = 0; for(int j = 1; j <= leny; j++) { if(x[i] == y[j]) t = j; p[i][j] = t; } } } LL solve() { int lenx = strlen(x+1); int leny = strlen(y+1); memset(f, 0, sizeof(f)); for(int i = 0; i <= lenx; i++) f[i][0] = 1; for(int j = 0; j <= leny; j++) f[0][j] = 1; for(int i = 1; i <= lenx; i++) { for(int j = 1; j <= leny; j++) { if(dp[i-1][j] == dp[i][j]) f[i][j] = (f[i][j] + f[i-1][j]) % mod; if(p[i][j] && dp[i-1][p[i][j]-1]+1==dp[i][j]) f[i][j] = (f[i][j] + f[i-1][p[i][j]-1]) % mod; } } return (int)f[lenx][leny]; } int main() { int T; scanf("%d", &T); while(T--) { inin(); LL ans = solve(); printf("%I64d\n", ans); } return 0; }