T1:http://www.gdfzoj.com/oj/contest/161/problems/9
因为宝藏拿了就没了,所以注意循环顺序
代码:
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
struct node
{
int end,t;
};
const int maxSize=100;
vector <node> M[maxSize+5];
int v[maxSize+5],f[maxSize+5][maxSize+5];
int k,m,n;
void dfs(int x,int fa)
{
int i,y,ti,k1,j;
f[x][0]=v[x];
for (i=0;i<M[x].size();i++)
{
y=M[x][i].end;
ti=M[x][i].t;
if (y!=fa)
{
dfs(y,x);
for (j=m;j;j--)//j、k1要倒着循环
{//如果正着来就会在加f[x][...]时会重复加f[y][k1],因为f[x][...]已经算了f[y][k1]
for (k1=j-2*ti;k1>=0;k1--)
f[x][j]=max(f[x][j],f[y][k1]+f[x][j-k1-2*ti]);
}
}
}
return ;
}
int main()
{
int i,x,y,w,ans;
node n1;
freopen("a.txt","r",stdin);
while (scanf("%d",&n)!=EOF)
{
memset(v,0,sizeof(v));
memset(f,0,sizeof(f));
for (i=1;i<=n;i++)
scanf("%d",&v[i]);
for (i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
n1.end=y; n1.t=w;
M[x].push_back(n1);
n1.end=x;
M[y].push_back(n1);
}
scanf("%d%d",&k,&m);
dfs(k,k);
ans=0;
for (i=0;i<=m;i++)
ans=max(ans,f[k][i]);
printf("%d\n",ans);
}
return 0;
}
T2:http://www.gdfzoj.com/oj/contest/161/problems/10
思路详见qq空间
程序方面:
1.写程序前,必须详细推出dp公式(哪种情况求和,哪种情况直接取值)
不要推到一半感觉就是这样就上了~
2.dp中为了min的maxValue不要过大(会爆)适当即可
3.对于特殊情况(叶子结点、根结点)
若dp公式中有min、max,则可以直接赋maxValue或0值(max、min时会筛掉)
可以省略特判
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxSize=10000,maxValue=1000000;
int n;
vector <int> M[maxSize+5];
int f[maxSize+5][3];
void dfs(int x,int fa)
{
int i,y;
f[x][0]=1; f[x][2]=maxValue;
//若是叶子结点被附最值也无妨(最后会被min排除掉)
//这里maxValue最好不要赋值过大(适当即可,会爆)
for (i=0;i<M[x].size();i++)
{
y=M[x][i];
if (y!=fa)
{
dfs(y,x);
f[x][0]+=min(f[y][1],f[y][0]);
//这里是+,不是直接min
//其他子树只是有可能结点不选,但子结点选
f[x][1]+=f[y][2];
}
}
for (i=0;i<M[x].size();i++)
{
y=M[x][i];
if (y!=fa)
f[x][2]=min(f[x][2],f[x][1]-f[y][2]+f[y][0]);
}
}
int main()
{
int i,x,y,ans;
freopen("a.txt","r",stdin);
while (scanf("%d",&n))
{
if (n==-1)
break;
if (n==0)
continue;
for (i=1;i<=n;i++)
{
f[i][0]=1; f[i][2]=maxValue;
M[i].clear();
}
for (i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
M[x].push_back(y);
M[y].push_back(x);
}
dfs(1,1);
ans=min(f[1][0],f[1][2]);
printf("%d\n",ans);
memset(f,0,sizeof(f));
}
return 0;
}