T1:神经网络
考察知识:图的基本知识,细节
算法难度:XX+ 实现难度:XX+
分析:
这道题不难,但是细节有点多(见反思)
我们考虑节点时需要使用上一个节点的值(所以要反向建图),所以可以用函数的递归调用实现
转移方程:
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
#define ll long long
//j->i Ci=sum(Cj*w(j,i))-Ui
struct edge{
int to,next;
ll w;
}e[maxn*50];
int first[maxn],np;
void add(int u,int v,ll w){
e[++np]=(edge){v,first[u],w};
first[u]=np;
}
ll C[maxn],U[maxn];//谨慎一点,用long long
int n,m,cd[maxn];
bool done[maxn];
void dfs(int i){
if(C[i]||done[i]) return;
for(int p=first[i];p;p=e[p].next){
int j=e[p].to;
ll w=e[p].w;
dfs(j);
if(C[j]<0) continue;//注意
C[i]+=C[j]*w;
}
C[i]-=U[i];
done[i]=true;//类似于记忆化搜索
}
int main(){
int u,v;
ll w;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld%lld",C+i,U+i);
for(int i=1;i<=m;i++){
scanf("%d%d%lld",&u,&v,&w);
add(v,u,w);//反向建图
cd[u]++;
}
int cnt=0;
for(int i=1;i<=n;i++) if(!C[i])
dfs(i);
for(int i=1;i<=n;i++) if(C[i]>0&&cd[i]==0){
printf("%d %lld\n",i,C[i]);cnt++;
}
if(!cnt) printf("NULL\n");
return 0;
}
反思:
题目部分截图:
扫描二维码关注公众号,回复:
2654002 查看本文章
我没有搞清楚题意!当场100-->20,惨不忍睹,T1差点爆零
我先解释一下图片表达的信息:
图一:说明神经元没有处于兴奋状态,它就不会向其他神经元传送信号(-40)
图二:只输出出度为0且满足Ci<0的点(-80)
情况三:考虑只有一个点的情况(-20)
然而我忽略了图一的信息,没有看见图二的要求,没有考虑情况三,于是错(W)误(A)百出,T_T
T2:
T3:加分二叉树
考察知识:二叉树的遍历,序列型动态规划
算法难度:XX+ 实现难度:XXX
分析:
考察二叉树的遍历:
中序遍历先遍历左子树然后当前根节点再然后右子树
前序遍历先遍历当前根节点然后左子树再然后右子树
二叉树的遍历是递归定义的,所以我们可以递归解决(加记忆化节省时间)
而这道题求最大分数,用动态规划解决:
定义状态方程:f(i,j)表示中序遍历序列为i到j的二叉树的最大得分
状态转移方程:
细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=35;
ll ans,f[maxn][maxn];
bool vis[maxn][maxn];
int n,a[maxn],root[maxn][maxn];
ll dp(int l,int r){
if(l>r) return 1;
if(l==r) return (ll)a[l];
if(vis[l][r]) return f[l][r];
ll T;
for(int rt=l;rt<=r;rt++){
T=dp(l,rt-1)*dp(rt+1,r)+a[rt];
if(T>f[l][r]) f[l][r]=T,root[l][r]=rt;//记忆路径
}
vis[l][r]=true;
return f[l][r];
}
void out(int l,int r){//输出路径
if(l>r) return;
if(l==r){printf("%d ",l);return;}
int rt=root[l][r];
printf("%d ",rt);//相当于二叉树的前序遍历
out(l,rt-1);
out(rt+1,r);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
printf("%lld\n",dp(1,n));
out(1,n);
return 0;
}
T4: