刷题记之代码能力大作战一

来源:互联网 发布:htpp js.ynjy.cn 编辑:程序博客网 时间:2024/04/29 05:39

最近突然发现自己真的好弱,刷题量真的好少,代码能力明显不足,于是决定狂刷题目,现在暂时按照hdu的分类刷一刷,不管难易,先提高一下自己的思维和代码能力。

今天过的题目:
Hdu 1080、1087、1081、1114、4705、1159.

Hdu 1080 简单dp递推,前缀和
Hdu 1087 简单dp递推
Hdu 1081 最大子矩阵和
Hdu 1114 简单dp递推(怎么感觉像个背包?!)
Hdu 4705 树形dp
Hdu 1159 最长公共子序列
Hdu 1165 打表找规律

Hdu 4705:
计算某棵子树(根结点为u)时分三种情况讨论:
①A、B、C分别属于u的三棵子树
②其中一个点为u,剩下两个点在u的某一棵子树上
③其中两个点在u的同一棵子树上,另一个在另一棵子树上
刚好前天在bc上看到一种计数方法,类似得用到这道题上,简化了好多,so good!

//Hdu 4705#pragma comment(linker, "/STACK:16777216")#include<iostream>#include<vector>#include<algorithm>#include<cstdio>using namespace std;typedef long long ll;const int N=1e5+10;ll siz[N], siz2[N];ll ans;vector<int>G[N];void Init(int n){    for(int i=0; i<=n; ++i)    {        G[i].clear();        }    ans=0;    }void AddEdge(int a, int b){    G[a].push_back(b);    G[b].push_back(a);}void dfs(int u, int fa){    siz[u]=1;    siz2[u]=0;    for(int i=0; i<G[u].size(); ++i)    {        int v=G[u][i];        if(v==fa) continue;        dfs(v, u);        ans+=siz2[u]*siz[v]+siz2[v]*siz[u];        siz2[u]+=siz2[v]+(siz[u]-1)*siz[v];        siz[u]+=siz[v];    }}int main(){    int n;    while(~scanf("%d", &n))    {        Init(n);        for(int i=0; i<n-1; ++i)        {            int x, y;            scanf("%d%d", &x, &y);            AddEdge(x, y);        }        dfs(1, 0);        printf("%I64d\n", ans);    }    return 0;}

Hdu 1165:
一开始以为直接记忆话搜索,结果很快发现爆栈了,因为f(m, n)当m=3, n=23时,f(3, 23)=67108861, 这时候去算f(2, f(3, 23))肯定是跑不出来的,最后打表发现,当m等于2时,f(m, n)=2*n+3,当m等于1时,f(m, n)=n+2,然后根据m=3时的计算公式,直接退出f(3,n)就可以了。

#include<cstdio>using namespace std;const int N=33;typedef long long ll;ll dp[N];ll f(int m, int n){    if(m==1) return n+2;    if(m==2) return 2*n+3;    return dp[n];}void init(){    for(int i=0; i<=24; ++i)    {        if(!i) dp[i]=f(2, 1);        else dp[i]=2*dp[i-1]+3;    }}int main(){    init();    int n, m;    while(~scanf("%d%d", &m, &n))    {        printf("%I64d\n", f(m, n));    }     return 0;}
0 0
原创粉丝点击