HDU 2196 Computer(树形dp经典)
题意:给出一棵树,求离每个节点最远的点的距离;
code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e4 + 50;
struct node {
int nex, dis;
};
vector<node> dge[maxn];
int d[maxn], f[maxn], son[maxn], maxxx[maxn];//d为x子树最大距离,son为子树最大距离经过的点;
//maxxx为次大的子树距离,f为x经过其父亲节点的最大距离;
bool vis[maxn];
//void dp(int x, int diss) {
// vis[x] = true;
// int maxx = 0;
// int len = dge[x].size();
// for(int i = 0; i < len; i++) {
// int y = dge[x][i].nex;
// if(vis[y]) continue;
// int dis = dge[x][i].dis;
// dp(y, diss + dis);
// if (d[y] + dis > maxx) {
// maxx = d[y] + dis;
// pre[y] = x;
// }
// }
// d[x] = maxx;
// int anss = diss;
// for (int i = 0; i < len; i++) {
// int y = dge[x][i].nex;
// if(vis[y])
// continue;
// if(pre[y] != x)
// anss = max(anss, d[y]);
// }
// maxxx[x] = anss;
// vis[x] = false;
// return;
// }
void dp(int x) {
vis[x] = true;int len = dge[x].size();
for(int i = 0; i < len; i++) {
int y = dge[x][i].nex; int dis = dge[x][i].dis;
if(vis[y]) continue;
dp(y);
if(d[y] + dis > d[x]) {
maxxx[x] = d[x];
d[x] = d[y] + dis;
son[x] = y;
}
else if(d[y] + dis > maxxx[x]) {
maxxx[x] = d[y] + dis;
}
}
}
void dfs(int x) {
vis[x] = true; int len = dge[x].size();
for (int i = 0; i < len; i++) {
int y = dge[x][i].nex; int dis = dge[x][i].dis;
if(vis[y]) continue;
if(son[x] == y)
f[y] = max(maxxx[x],f[x])+dis;
else
f[y] = max(d[x],f[x])+dis;
dfs(y);
}
}
int main() {
// freopen("in.txt", "r", stdin);
int n;
while(~scanf("%d", &n)) {
for(int i = 1; i <= n; i++) {
dge[i].clear(); d[i] = 0; vis[i] = false;
}
int pos; node path;
for(int i = 2; i <= n; i++) {
scanf("%d%d", &pos, &path.dis);
path.nex = i; dge[pos].push_back(path);
path.nex = pos; dge[i].push_back(path);
}
int st = 1; dp(st);
for(int i = 1; i <= n; i++) vis[i] = false; f[st] = 0;
dfs(st);
for (int i = 1; i <= n; i++) {
// printf("%d\n", d[i]);
// printf("%d\n", maxxx[i]);
// printf("%d %d\n", i,max(f[i], d[i]));
printf("%d\n", max(f[i], d[i]));
}
}
return 0;
}
南昌邀请赛网络赛
D Match Stick Game
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const ll INF = -1e14;
int num[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
ll st[2][10][100];
void init()
{
for(int i = 0;i<10;i++) for(int j = 0;j<100;j++)
{
st[0][i][j] = -INF;
st[1][i][j] = INF;
}
for(int j = 1; j <= 9; j++)
{
st[1][1][num[j]] = max(st[1][1][num[j]], j * 1ll);
st[0][1][num[j]] = min(st[0][1][num[j]], j * 1ll);
}
for(int i = 2; i < 10; i++)
{
for(int j = 0; j <= 9; j++)
{
for(int k = 100; k >= num[j]; k--)
{
st[1][i][k] = max(st[1][i][k], st[1][i - 1][k - num[j]] * 10 + j);
st[0][i][k] = min(st[0][i][k], st[0][i - 1][k - num[j]] * 10 + j);
}
}
}
st[0][1][6] = 0;
}
ll dp[105][1005];
char s[100];
int lens[105], lenn;
int main()
{
// freopen("in.txt", "r", stdin);
init();
int T;
scanf("%d", &T);
while(T--)
{
int n; lenn = 0; int sum = 0;
scanf("%d", &n); scanf("%s", s);
int len = strlen(s); int cnt = 0;
for(int i = 0; i < len; i++)
{
if(s[i] == '+' || s[i] == '-')
{
lens[lenn++] = cnt;
cnt = 0;
}
else cnt++;
if(s[i] == '-') sum += 1;
else if(s[i] == '+') sum += 2;
else sum += num[s[i] - '0'];
}
lens[lenn++] = cnt;
for(int i = 1;i<=n;i++) for(int j = 0;j<=sum;j++) dp[i][j] = INF;
len = lens[0];
int totl = 2, totr = min(sum, 7*len);
for(int j = totl; j <= totr; j++) dp[1][j] = max(dp[1][j], st[1][len][j]);
n = lenn;
for(int i = 2; i <= n; i++)
{
len = lens[i - 1];
for(int j = totr; j >= totl; j--)
{
for(int k = 2 * len; k <= 7 * len; k++)
{
dp[i][j + 2 + k] = max(dp[i - 1][j] + st[1][len][k], dp[i][j + 2 + k]);
dp[i][j + 1 + k] = max(dp[i - 1][j] - st[0][len][k], dp[i][j + 1 + k]);
}
}
totr = min(sum, totr + 7 * len + 2);
totl = totl + 2 * len + 1;
}
printf("%lld\n", dp[n][sum]);
}
return 0;
}
I Max answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 50;
struct Node
{
ll val;
int l, r;
} v[maxn];
ll s[maxn];
stack<int> st;
int main()
{
// freopen("in.txt", "r", stdin);
int n; ll x; cin >> n; s[0] = 0;
for(int i = 1; i <= n; i++)
{
cin >> x; s[i] = s[i - 1] + x;
v[i].l = v[i].r = i; v[i].val = x;
}
v[0].val = -0x3f3f3f3f;
v[n + 1].val = -0x3f3f3f3f; v[n + 1].l = v[n + 1].r = n + 1;
int i = 1;
while(i <= n + 1)
{
if(st.empty() || v[i].val > v[st.top()].val)
st.push(i++);
else
{
v[i].l = v[st.top()].l;
st.pop();
}
}
while(!st.empty()) st.pop();
i = n + 1;
while(i >= 1)
{
if(st.empty() || v[i].val > v[st.top()].val)
st.push(i--);
else
{
v[i].r = v[st.top()].r;
st.pop();
}
}
ll ans = -0x3f3f3f3f;
for(int i = 1; i <= n; i++)
{
// cout << v[i].l << " " << v[i].r << endl;
ll tem = v[i].val * (s[v[i].r] - s[v[i].l - 1]);
ans = max(ans, tem);
}
ll sum = 0;
ll minn = 0x3f3f3f3f;
for(int i = 1; i <= n; i++)
{
if(sum + v[i].val < 0)
{
sum += v[i].val;
minn = min(minn, v[i].val);
ans = max(ans, minn * sum);
}
else sum = minn = 0;
}
cout << ans << endl;
return 0;
}