10月19日
今天的题除了第二题比较难,其他的都比较简单。第三题在考试的时候想到了动态规划,然而并没有写出来,所以写了一个0分的暴力。。
第二题没有写出来,最后只有T1得了100分。
———————————————————————————————————————————————————————————————————
对于T1:
一道十分简单的模拟+进制转换。
对于T2:
一开始想到的是并查集,然后发现并没有什么卵用,又想可不可以写网络流,发现也没有用。最后连暴力都不知道怎么写,醉了。。
好吧,正解是——搜索。
最简单的搜索办法:开始把P[0] ~ P[n-1]都未标号,每次枚举一个未标号的点和一个已标号的点,建立一条边。
同时考虑树的深度不能超过D,以及每个点的转发限制就可以搜出结果。然而时间爆炸。。。QAQ
加优化~~优化~~优化,重要的事情说三遍。。。把已经加入数的点标上序号,依照序号从小到大的顺序顺序枚举该节点的儿子节点。
在递归的每一层,枚举了一个节点指定节点的儿子节点以后,深入至下一层是要么枚举下一个该指定节点的儿子节点,要么推移至序号加1
的指定节点寻找儿子节点。至此效率已优化至O(n/2)^2n。
对于T3:
又是动态规划的题目,考完后分析发现还是蛮简单的。由于实验基地的形状必须是“凹”形,所以我们考虑定义三个状态,用dp[i][0]、
dp[i][1]、dp[i][2]分别表示到第i列,左边部分、中间凹下去的部分、右部分的最优解,那么状态转移方程可以定义为:
dp[i][0] = max(dp[i-1][0],judge) + a[1][i] + a[2][i]; <---------左边部分
dp[i][1] = max(dp[i-1][1],dp[i-1][0]) + a[2][i];v <---------中间凹下去的部分
dp[i][2] = max(dp[i-1][2],dp[i-1][1]) + a[1][i] + a[2][i];<---------右部分
于是本题得以完美解决。
———————————————————————————————————————————————————————————————————
下面附上代码:
今天的题除了第二题比较难,其他的都比较简单。第三题在考试的时候想到了动态规划,然而并没有写出来,所以写了一个0分的暴力。。
第二题没有写出来,最后只有T1得了100分。
———————————————————————————————————————————————————————————————————
对于T1:
一道十分简单的模拟+进制转换。
对于T2:
一开始想到的是并查集,然后发现并没有什么卵用,又想可不可以写网络流,发现也没有用。最后连暴力都不知道怎么写,醉了。。
好吧,正解是——搜索。
最简单的搜索办法:开始把P[0] ~ P[n-1]都未标号,每次枚举一个未标号的点和一个已标号的点,建立一条边。
同时考虑树的深度不能超过D,以及每个点的转发限制就可以搜出结果。然而时间爆炸。。。QAQ
加优化~~优化~~优化,重要的事情说三遍。。。把已经加入数的点标上序号,依照序号从小到大的顺序顺序枚举该节点的儿子节点。
在递归的每一层,枚举了一个节点指定节点的儿子节点以后,深入至下一层是要么枚举下一个该指定节点的儿子节点,要么推移至序号加1
的指定节点寻找儿子节点。至此效率已优化至O(n/2)^2n。
对于T3:
又是动态规划的题目,考完后分析发现还是蛮简单的。由于实验基地的形状必须是“凹”形,所以我们考虑定义三个状态,用dp[i][0]、
dp[i][1]、dp[i][2]分别表示到第i列,左边部分、中间凹下去的部分、右部分的最优解,那么状态转移方程可以定义为:
dp[i][0] = max(dp[i-1][0],judge) + a[1][i] + a[2][i]; <---------左边部分
dp[i][1] = max(dp[i-1][1],dp[i-1][0]) + a[2][i];v <---------中间凹下去的部分
dp[i][2] = max(dp[i-1][2],dp[i-1][1]) + a[1][i] + a[2][i];<---------右部分
于是本题得以完美解决。
———————————————————————————————————————————————————————————————————
下面附上代码:
T1:
using namespace std;
int x,i,n,a,j,sum,tot;
string strings;
int last[64010],ans[64010];
int getint()
{
char c = getchar();
int f = 1,k = 0;
if(c == '-') f = -1;
for(; c < '0' || c > '9'; c = getchar());
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * f;
}
string change(int a)
{
char s[9] = {'0','0','0','0','0','0','0','0'};
string ss;
int tot = -1;
while(a != 0)
{
x = a % 2;
s[++tot] = x + '0';
a /= 2;
}
for(int j = 7; j >= 0; j--)
{
ss += s[j];
}
return ss;
}
int main()
{
string s1;
n = getint();
for(i = 1; i <= n / 8; i++)
{
a = getint();
s1 = change(a);
for(j = 0; j <= s1.size()-1; j++)
strings += s1[j];
}
//cout << strings << endl;
tot = 0;
sum = 1;
last[++tot] = strings[0] - '0';
for(i = 1; i <= strings.size()-1; i++)
{
if(last[tot] != strings[i] - '0')
{
if(strings[i-1] - '0' == 1)
ans[tot] = 128 + sum;
else
ans[tot] = sum;
sum = 1;
last[++tot] = strings[i] - '0';
}
else
{
sum++;
}
}
if(strings[i-1] - '0' == 1)
ans[tot] = 128 + sum;
else
ans[tot] = sum;
for(i = 1; i <= tot - 1; i++)
{
cout << ans[i] << " ";
}
cout << ans[tot] << endl;
return 0;
}
T2:
还没调出来。。
T3:
using namespace std;
long long dp[500010][3];
int a[3][500010],i,j,n;
int getint()
{
char c = getchar();
int f = 1,k = 0;
if(c == '-') f = -1;
for(; c < '0' || c > '9'; c = getchar());
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * f;
}
int main()
{
n = getint();
for(i = 1; i <= 2; i++)
{
for(j = 1; j <= n; j++)
{
a[i][j] = getint();
}
}
long long judge = 0;
for(i = 1; i <= n; i++)
{
dp[i][0] = max(dp[i-1][0],judge) + a[1][i] + a[2][i];
if(i >= 2)dp[i][1] = max(dp[i-1][1],dp[i-1][0]) + a[2][i];//注意这里要写i>=2,下面要写i>=3。因为左边必
if(i >= 3)dp[i][2] = max(dp[i-1][2],dp[i-1][1]) + a[1][i] + a[2][i];//须先选,再选中间和右边
}
long long maxx = -10000000000;
for(i = 1; i <= n; i++)
maxx = max(maxx,dp[i][2]);
cout << maxx << endl;
return 0;
}