18.1.1考试

今天考的题目都是DP,本来以为会有什么图论...根据今天题目比较水的原因,我直接放解题报告,大家应该可以看得懂。。

T1

Source

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn=10000+10,maxm=10010;
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
int time[10010],x[10010],y[10010];
int dp[maxm];
int gi(){
    int sum=0,f=1;
    char ch=getchar();
    while(ch>‘9‘ || ch<‘0‘){
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch<=‘9‘ && ch>=‘0‘){
        sum=sum*10+ch-‘0‘;
        ch=getchar();
    }
    return sum*f;
}
int max(int a,int b){
    if(a>b)return a;
    return b;
}
int can(int i,int j){
    if((abs(x[i]-x[j])+abs(y[i]-y[j]))<=time[i]-time[j])return 1;
    return 0;
}
int main(){
    file("dabai");
    int i,j,k,n,m,ans=0;
    n=gi();m=gi();
    for(i=1;i<=m;i++){
        time[i]=gi();x[i]=gi();y[i]=gi();
        dp[i]=1;
        for(j=1;j<i;j++)
            if(can(i,j))
                dp[i]=max(dp[i],dp[j]+1);
        ans=max(ans,dp[i]);
    }
    printf("%d\n",ans);
    return 0;
} 

T1

T2

source

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
const int Mod=1e9+7;
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
int n;
int dp[11];
int a[11],b[11],ans;
int max(int a,int b){
    return a>b?a:b;
}
int LIS(){
    int sum=0;
    for(int i=1;i<=n;i++){
        dp[i]=1;
        for(int j=1;j<i;j++)
            if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);
        sum=max(sum,dp[i]);
    }
    return sum;
}
void dfs(int i){
    if(i>n){
        int k=LIS();
        if(k<=2)ans++;
        return;
    }
    for(int j=1;j<=n;j++)
        if(!b[j]){
            b[j]=1;a[i]=j;
            dfs(i+1);
            b[j]=0;
        }
}
long long qsm(int a,int p){
    long long cnt=1;
    while(p){
        if(p&1)cnt=(cnt*a)%Mod;
        p>>=1;a=(a*a)%Mod;
    }
    return cnt;
}
long long C[1010];
long long inv[1010];
int main(){
    file("repair");
    int i,j,k,m;
    scanf("%d",&n);
    inv[1]=1;
    for(i=2;i<=n+1;i++)
        inv[i]=((Mod-Mod/i)*(inv[Mod%i]))%Mod;
    /*
        dfs(1);
        O((n^2)*n!)
    */
    C[1]=1;
    for(i=2;i<=n;i++)
        C[i]=(((C[i-1]*(4*i-2))%Mod)*inv[i+1])%Mod;
    printf("%lld\n",C[n]);
    return 0;
}
/*
1432

2143
2413
2431

3142
3214
3241
3412
3421

4132
4213
4231
4312
4321
*/

T2

T3

Source

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
const int maxm=1000010,maxn=500000+10;
struct node{
    int to,next,w;
}e[maxm];
int front[maxn],cnt;
long long max(long long a,long long b){
    return a>b?a:b;
}
void Add(int u,int v,int w){
    e[++cnt].to=v;e[cnt].w=w;
    e[cnt].next=front[u];
    front[u]=cnt;
}
long long dis[maxn];
int vis[maxn];
void dfs1(int u){
    for(int i=front[u];i;i=e[i].next){
        int v=e[i].to;
        if(vis[v])continue;
        vis[v]=1;
        dfs1(v);
        vis[v]=0;
        dis[u]=max(dis[u],dis[v]+e[i].w);
    }
}
long long ans;
void dfs(int u){
    for(int i=front[u];i;i=e[i].next)
        if(!vis[e[i].to]){
            vis[e[i].to]=1;
            dfs(e[i].to);
            int v=e[i].to;
            ans=ans+dis[u]-dis[v]-e[i].w;
        }
}
int main(){
    file("daodan");
    int i,j,k,n,m,root;
    scanf("%d",&n);
    scanf("%d",&root);
    for(i=1;i<=n;i++){
        int x,y,w;
        scanf("%d%d%d",&x,&y,&w);
        Add(x,y,w);Add(y,x,w);
    }
    vis[root]=1;
    dfs1(root);
    //for(i=1;i<=n;i++)
    //    printf("%d:%d\n",i,dis[i]);
    memset(vis,0,sizeof(vis));
    vis[root]=1;
    dfs(root);
    printf("%lld\n",ans);
    return 0;
}

T3

T4

Source

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
const int maxn=100000+10,maxm=200000+10;
struct node{
    int to,next,w;
}e[maxm];
int front[maxn],cnt;
void Add(int u,int v,int w){
    e[++cnt].next=front[u];
    front[u]=cnt;e[cnt].w=w;
    e[cnt].to=v;
}
int k,n;
long long  dp[maxn][110];
long long min(long long a,long long b){
    return a<b?a:b;
}
long long max(long long a,long long b){
    return a>b?a:b;
}
long long dfs(int u,int fa,int K){
    if(dp[u][K])return dp[u][K];
    long long sum=0,cnt=0;
    for(int i=front[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa)continue;
        if(!sum)sum=dfs(v,u,K)+e[i].w;
        else sum=max(sum,dfs(v,u,K)+e[i].w);
        if(K!=0){
            if(!cnt)cnt=dfs(v,u,K-1)+e[i].w;
            else cnt=min(cnt,dfs(v,u,K-1)+e[i].w);
        }
    }
    dp[u][K]=min(cnt,sum);
    return dp[u][K];
}
int main(){
    file("find");
    int i,j,m;
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=m;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        Add(u,v,w);
    }
    printf("%lld\n",dfs(1,-1,k));
    return 0;
}

T4

今天考试最遗憾的就是所有题目都想出来了正解,但后面两题都是打萎了。。。

原文地址:https://www.cnblogs.com/cj-gjh/p/8167785.html

时间: 2024-11-08 23:23:25

18.1.1考试的相关文章

18.8.13 考试总结

1.1 问题描述请构造一颗n 个节点的树,使得其价值最大.f(d) 表示树上,度数为d 的一个点能够获取的价值.这棵树的价值为Σni=1 f(di)di 表示第i 个点的度数1.2 输入第一行一个整数T,接下来T 组数据,每组数据输入两行.第一行输入整数n.第二行输入n ?? 1 个整数f(i) 代表f(1) f(n ?? 1).1.3 输出对于每组数据输出一行,为能够构造的树的最大价值. 一开始我以为是一道树形dp... 考完了才知道原来这个是一道背包问题 n个节点 总共有2n - 2个度数

18.8.26 考试总结

我真的服了 我考试的时候这道题题都是读错了的 交了个挖挖机结果还狗了20分.. 这道题是一道找规律的题 看完题很显然能够发现我们可以将相同颜色的连通块缩点 因为同一个联通块的可以一次操作全部变成另外一种颜色 所以就缩点就好了.. 对于缩点后的一条链 每次我们可以将一个点变色 那么和他相邻的点就和他颜色一样 然后就再次缩点 所以每次链的长度都可以 -2 所以说最后缩点的次数就是  点的个数 / 2  (下取整) 但是这是对于一条链 那么对于一棵树而言呢? 其实是一样的 因为每次搞这个操作 我们都可

18.9.22 考试总结

这道题一看就是可持久化并查集 然后我就愉快的yy了一波 还是错掉了qwqwqwqwq 方法是对的 就是我每次在树上查询$fa$的时候我还压缩了路径 导致这玩意空间炸掉了 所以要保证时间复杂度 就启发式合并 也就是$size$小的往$size$大的搞 这样子就保证每次合并的时候连通块元素个数每次至少乘以$2$ 也就是保证了层数是$log$级的 代码 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; int n

18.8.17 考试总结

高斯消元[问题描述]everlasting 觉得太无聊了,于是决定自己玩游戏! 他拿出了n 个小圆,第i 个的颜色是ai.接着他将这n 个小圆复制m 次并依次连接起来. 之后他发现其中有很多颜色相同的小圆,于是他决定:每有k 个连续颜色相同的小圆就将他们消去, 并将剩下的依次连接.(注意只会消除k个,即使有超过k 个)他将每次从头开始不断进行这个操作直到无法操作为止. 他想知道最后能剩下多少个小圆? [输入格式] 从文件guass.in 中输入数据. 第一行三个正整数n,m,k,表示开始小圆的个

18.8.19 考试总结

Gift[问题描述]人生赢家老王在网上认识了一个妹纸,然后妹纸的生日到了,为了表示自己的心意,他决定送她礼物. 可是她喜爱的东西特别多,然而他的钱数有限,因此他想知道当他花一定钱数后剩余钱数无法再购买任何一件剩余物品 (每种物品他最多买一个)时有多少种方案,两种方案不同,当且仅当两种方案中至少有一件品不 同,可是由于他忙着准备泡下一个妹纸(chi),因此麻烦聪明的你帮帮忙. [输入格式] 输入第一行 n 和m,n 表示妹纸喜欢的礼物数目,m 表示现有的钱数,第二行n 个数,表示n 个物品的价格.

18.8.31 考试总结

这道题就是打表找规律 然而我打表并没有找到规律... yyyuuudalao就找到了tqltql%%% 打表发现 $ A $ 数列是这样子1 1 ,2 ,2 ,6 1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9 10 10 11 12 12 12 13 14 14 15 16 16 16 16 16... $ t[i] $ 表示 $ i $ 这个数出现次数 然后发现 $t[i]$ 为 $i$ 所含的因子 $2$ 个数 $+ 1$ ($1$除外) 也就是说每个数如果多一个 $2

18.9.7 考试总结

啊今天是生日之后的第三天呢 然后我就大凶了.. 略微难受 啊这道题正解是倒着搞得 ()然而蒟蒻我并不会... 于是就学习wans大佬的程序写的二分 + 正着搞得$Spfa$ $Spfa$最坏是 $nm$ 显然这道题是可以直接跑过的 所以对于起点二分一个最大货物量 然后Spfa跑每个点的最大值就可以了 按照题目意思来稿还是很清楚的 代码 #include <bits/stdc++.h> #define oo 10000000 using namespace std; const int N =

18.9.8 考试总结

这道题就是树上贪心就好了 从下往上搞 要是遇到没有被选过得点就把他的父亲标记就好了 然后就 $bfs$ 把节点都存到一个栈里面 然后弹出的肯定是最深的点 就慢慢往上搞就可以了 代码 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; int stk[N],tot,top,fa[N],ans = 0; int n,head[N],nex[2 * N],tov[2 * N]; bool vis[N],arr[N]

18.10.4 考试总结

这道题就是一道肥!肠!裸!的!轮廓线dp 然后因为细节太多了还因为有一个sbsbsb编译错误 就是不准我函数名字取count...我恨 我永远讨厌轮廓线dp 代码 #include <bits/stdc++.h> using namespace std; const int N = 1e6 + 5; int dp[2][N],n,m,len[200],cnt[N],ans; char s[200][40]; void Init( ) { scanf("%d%d",&