暑假第十四测

题解:

第一题:nlogn LIS

#include<bits/stdc++.h>
using namespace std;
const int M = 100005;
int a[M], f[M];
int main(){
    freopen("lis.in","r",stdin);
    freopen("lis.out","w",stdout);
    int n, cnt = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        if(a[i] > f[cnt])f[++cnt] = a[i];
        else {
            int pos = lower_bound(f+1, f+1+cnt, a[i]) - f;
            f[pos] = a[i];
        }
    }
    printf("%d\n", cnt);
}

第二题:树上背包,dp[u][i]表示以u为子树连续大小为i最少砍多少刀;答案就是max(dp[u][k] -1) 减去和父亲连的一条边

dp[u][k] = min( dp[u][k],  dp[u][p] + dp[v][k - p] - 1) (我们一个一个子树考虑,多一棵树就可以少砍一条边)

dp[u][1] = degree[u];

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int M = 155, inf = 1e8;
int siz[M], n, k, h[M], dp[M][M], du[M], tot, zz = inf;
struct edge{int v, nxt;}G[M << 1];
void add(int u, int v){G[++tot].v = v; G[tot].nxt = h[u]; h[u] = tot;}

void dfs(int u, int fa){
    //dp[u][0] = 0;
    if(u != 1)du[u]--;
    dp[u][1] = du[u];
    siz[u] = 1;
    int child = 0;
    for(int i = h[u]; i; i = G[i].nxt){
        int v = G[i].v;
        if(v == fa)continue;
        dfs(v, u);
        child++;
        siz[u] += siz[v];

    }
    for(int i = h[u]; i; i = G[i].nxt){
        int v = G[i].v;
        if(v == fa)continue;
        int s1 = min(siz[u], k), s2;
            for(int p = s1; p > 1; p--){
                s2 = min(p - 1, siz[v]);
                for(int z = 1; z <= s2; z++){
                    if(dp[u][p - z] < inf)
                        dp[u][p] = min(dp[u][p], dp[u][p - z] + dp[v][z] - 1);
                }
            }    

    }

    if(u != 1)zz = min(zz, dp[u][k] + 1);
    else zz = min(zz, dp[u][k]);
}

int main(){
    freopen("isolate.in","r",stdin);
    freopen("isolate.out","w",stdout);
    scanf("%d%d", &n, &k);
    int u, v;
    for(int i = 1; i < n; i++){
        scanf("%d%d", &u, &v);
        add(u, v); add(v, u);
        du[u]++; du[v]++;
    }
    //memset(mx, 127, sizeof(mx));
    memset(dp, 127, sizeof(dp));
    dfs(1, 0);
    /*for(int i = 1; i <= n; i++){

        for(int j = 1; j <= k; j++)printf("%d %d\n", dp[i][j], dp[i][j]);
        printf("      %d\n", i);
    }*/

    printf("%d\n", zz);
}

第三题:状压dp,原题

#include<bits/stdc++.h>
using namespace std;
long long dp[12][1 << 11];
int w[1 << 11][1 << 11], r, c;

void dfs(int dep, int os, int ns){
    if(!dep) w[ns][++w[ns][0]] = os;
    else{
        if( ( (1<<(dep - 1)) & os ) == 0){
            dfs(dep - 1, os, ns + (1 << (dep - 1)));
        }
        else{
            dfs(dep - 1, os, ns);
            if(dep >= 2 && ( os & (1 << (dep - 2)) ) )
                dfs(dep - 2, os, ns + (1 << (dep - 1)) + (1 << (dep - 2)));
        }
    }
}

void init(){

    for(int s1 = 0; s1 < (1 << r); s1++)
        dfs(r, s1, 0);
}

int main(){
    freopen("domino.in","r",stdin);
    freopen("domino.out","w",stdout);
    scanf("%d%d", &r, &c);
    if(r * c % 2){
        puts("0");return 0;
    }
    if(r > c)swap(r, c);
    init();
    dp[0][(1 << r) - 1] = 1;
    for(int i = 1; i <= c; i++){
        for(int s = 0; s < ( 1 << r ); s++){
            for(int k = 1; k <= w[s][0]; k++)
                dp[i][s] += dp[i - 1][w[s][k]];
        }
    }
    printf("%I64d\n",dp[c][(1 << r) - 1]);
}

第四题:背包,dp[p][s]表示选择了总共p元,是否可以凑出s元;

dp[p][s] |= dp[p - c[i]][s - c[i]] | dp[p - c[i]][s]; 最后看dp[k][i] ?= 1;

我觉得我应该重学背包

#include<bits/stdc++.h>
using namespace std;
const int M = 505;
bool f[M][M];
int c[M], tp[M], tong[M], tot;

int main(){
    freopen("coin.in","r",stdin);
    freopen("coin.out","w",stdout);
    int n, k, sum = 0;
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)scanf("%d", &c[i]);
    f[0][0]=1;
    for(int i = 1; i <= n; i++)
        for(int p = k; p >= c[i]; p--)
            for(int s = k; s >= 0; s--){
                f[p][s] |= f[p - c[i]][s];
                if(s >= c[i])f[p][s] |= f[p - c[i]][s - c[i]];
            }
    for(int i = 0; i <= k; i++)
        if(f[k][i])tp[++tot] = i;
    printf("%d\n", tot);
    for(int i = 1; i <= tot; i++)printf("%d ", tp[i]);
}

原文地址:https://www.cnblogs.com/EdSheeran/p/9481839.html

时间: 2024-10-27 12:43:35

暑假第十四测的相关文章

暑假第二十四测

题解: 第一题:二分+贪心:二分距离上限,两端的人能从两端取就从两端取,这样可以为中间的做贡献: #include<bits/stdc++.h> using namespace std; const int M = 10005; int a[M], b[M], pos[M], x, n, m; bool id[M]; #define ll long long inline int ab(int a, int b){ if(a > b)return a - b; return b - a;

暑假第二十五测

以后WA了T了看数组: 暑假四次数组下标超界,多次数组开小,暂时没有访问到负下标 题解: 第一题:这道题可以转换为颜色相同的点缩成一个点,每次可以将两个点合并成同一点,问最少几次将所有点合并成一个点: 开始想到并查集+贪心合并度数最多的并查集,但这样是有问题的,比如度数一样时,选择的先后顺序是有影响的: 正解:缩点+找直径,如果是一条黑白相间的链,就是点数/2, 而树上任何一条直径都会有一个点经过直径,我们从交点开始往外延伸,发现最长延伸就是直径本身: 思想:从特殊到一般 #include<bi

暑假第十二测

题解:第一题: 打表找规律,从12以后每次加49,我一直在前十找规律,,找了半天,以后还是多打点,学聪明点 #include <bits/stdc++.h> #define ll long long using namespace std; int zl[4] = {1,5,10,50}; ll ans[] = {0,4,10,20,35,56,83,116,155,198,244,292,341,390,439,488,537,586,635,684,733,782,831,880,929,

暑假第二十六测

今天又考的奇差 题解: 第一题: 这么简单一道题我想了好久,智商实在是下线了: #include<bits/stdc++.h> using namespace std; int main(){ freopen("shortway.in","r",stdin); freopen("shortway.out","w",stdout); int n, k; scanf("%d%d", &n,

暑假第二十九测

第三题换成能否得到x, 可以1, 不可以-1 题解: 第一题:打表找规律: 打表发现a是:1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9-- 对于每一项Ai = i拆分成质因数中有多少个2 + 1:如果把桶也给打出来,就发现他是这样的: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 2 + 4 + 6 + 8 +  4  + 8 +  8 + 即2^i的等差数列,所以对一个数m我们就很容易确定他前面的数的和: 但是对于一个位置我们怎么找到他对应的m呢? 把上

【Git入门之十四】Git GUI

[Git入门之十四]Git GUI - JackyStudio - 博客频道 - CSDN.NET 文章都快写完了,Git GUI才浮出水面,很多人要骂我,这么方便的东西怎么不早拿出来. 当然命令行和图形界面各有千秋,个人觉得命令行更能让人清楚的掌握整个项目的代码线.当然萝卜青菜各有所爱,Windows,Linux也是一样.喜欢什么客官您挑.本文只做简单介绍. 1.Git GUI有什么? 霸气测漏的右键菜单和可视化管理界面. 2.初始化仓库 新建一个文件夹叫JackyGUI,右键点击Git In

第十四章 数组

第十四章 数组 1.  什么是数组 三要素:数组类型  数组名  下标 2.  数组元素 3.  数组下标越界 一旦越界程序就会报错 4.  倒序输出 5.  将数组的下标定义为常量以便于修改 6.  手动操作数组元素 7.  数组的初始化 空间不够报错,多了用0补 ① ② 字符数组的初始化 char array[10]={"hello"} 等价于char array[10]= "hello" char array[10]={'h','e','l','l','o',

汇编入门学习笔记 (十四)—— 直接定址表

疯狂的暑假学习之  汇编入门学习笔记 (十四)-- 直接定址表 参考: <汇编语言> 王爽 第16章 1. 描述单元长度的标号 普通的标号:a,b assume cs:code code segment a:db 1,2,3,4,5,6,7,8 b:dw 0 start: mov si,offset a mov di,offset b mov ah,0 mov cx,8 s: mov al,cs:[si] add cs:[di],ax inc si loop s mov ax,4c00h in

雅虎十四条 - 14个优化网站性能提高网站访问速度的技巧

14个优化网站性能提高网站访问速度的技巧 又叫“雅虎十四条”,想起一年前那个懵懂的我,大四傻乎乎的跑到大学城面试前端,那个时候以为寒暑假看了两套CSS的视频,就很牛B了,出发先还把视频温了一下,嗯嗯,这是滑动门,嗯嗯这是绝对定位,嗯嗯这是浮动清除…… 当时是彪叔面试我的,当时我还不知道那个人,全身黑漆漆的,黑色T-shirt,黑色皮肤,黑色帽子,黑色墨镜,还有点黑色胡渣的人,就是彪叔,补做了试题后支支吾吾的跟他谈了一下,发现完全不行,第一个问题是“雅虎十四条”是什么?然后我蒙了,pardon?