7.12训练日志

今天早上起来状态不如昨天,上来就做软件安装:

I. 软件安装

 
题目类型:传统 评测方式:文本比较
 
题目描述

现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一 些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的 是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。

我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一 次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

输入格式

第1行:N,M (0<=N<=100.0<=M<=500)

第2行:W1,W2,…,Wi,…,Wn(0<=Wi<=M)

第3行:V1,V2,…,Vi,…,Vn(0<=Vi<=1000)

第4行:D1,D2,…,Di,…,Dn(0<=Di<=N,Di≠i)

输出格式

一个整数,代表最大价值。

样例
样例输入
3 10
5 5 6
2 3 4
0 1 1
样例输出
5

这题上来就知道是反向建边,然后跑树批(树上dp)然后就开始码,并没有看标签,以为这就是上天赐予的水题,满怀信心要AC他,dp式子也写对了,也建虚根节点了,然而

惊喜爆10,一看标签,省选,靠,不是水题(宝宝不开心!)然后就想了一想,自己又手膜了一个样例然后就发现会出现环,例如1 3 2 1时就会出现环,所以需要什么?

tarjin(orz)缩点啊,然后,然后就A了;

码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<stack>
 6 using namespace std;
 7 #define LL long long
 8 //powered by lsc;
 9 const LL maxn=8000;
10 LL head[maxn],ver[maxn],nxt[maxn],tot,d[maxn],cntt;
11 struct chu{
12 LL x,y,head,nxt;
13 }s[maxn];                //edge;
14 
15 LL w[maxn],v[maxn],dp[3000][3000];
16 LL n,m,ans;            //problom;
17 
18 LL dfn[maxn],low[maxn],belong[maxn],cp[maxn],cnt,vis[maxn],cw[maxn];//cp is the v value,cw is the w value;
19 stack<LL>ss;
20 inline void add(LL x,LL y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
21 inline void ADD(LL x,LL y){s[++cntt].y=y;s[cntt].x=x;s[cntt].nxt=s[x].head;s[x].head=cntt;}
22 void dfs(LL x)
23 {
24     dfn[x]=low[x]=++cnt;
25     ss.push(x);
26     vis[x]=1;
27     for (LL i=s[x].head;i;i=s[i].nxt)
28         if (!dfn[s[i].y])
29             dfs(s[i].y),
30             low[x]=min(low[x],low[s[i].y]);
31         else if (vis[s[i].y])
32             low[x]=min(low[x],dfn[s[i].y]);
33     if (dfn[x]==low[x])
34     {
35         cp[x]=0;LL ress=0;
36         for (LL y=-1;y!=x;y=ss.top(),ss.pop())
37         {
38             belong[ss.top()]=x,
39             cp[x]+=v[ss.top()],
40             cw[x]+=w[ss.top()],
41             vis[ss.top()]=0;
42         }
43     }
44 }
45 void solve(LL x,LL fa)
46 {
47     for(LL i=cw[x];i<=m;i++)
48         dp[x][i]=cp[x];
49     for(LL i=head[x];i;i=nxt[i])
50     {
51         LL y=ver[i];
52         if(y==fa)continue;solve(y,x);
53         for(LL o=m-cw[x];o>=0;o--)
54             for(LL u=0;u<=o;u++)
55             dp[x][o+cw[x]]=max(dp[x][o+cw[x]],dp[y][u]+dp[x][o+cw[x]-u]);
56     }
57 }
58 int main()
59 {
60     //freopen("cnm.txt","r",stdin);
61     scanf("%lld%lld",&n,&m);
62     for(LL i=1;i<=n;i++)
63     scanf("%lld",&w[i]);
64     for(LL i=1;i<=n;i++)
65     scanf("%lld",&v[i]);
66     for(LL i=1;i<=n;i++){LL vp=0;scanf("%lld",&vp);if(vp==0)continue;ADD(vp,i);}
67     //for(LL i=1;i<=n;i++)if(d[i]==0)ADD(0,i);    //xu root;
68     for(LL i=1;i<=n;i++)if(!dfn[i])dfs(i);
69         for(LL j=1;j<=cnt;j++)
70         {
71             if(belong[s[j].x]!=belong[s[j].y])
72                 //printf("%d %d  start point value:%d end point value:%d\n",belong[i],belong[s[j].y],cw[belong[i]],cw[belong[s[j].y]]),
73                 add(belong[s[j].x],belong[s[j].y]),
74                 d[belong[s[j].y]]++;
75         }
76     for(int i=1;i<=n;i++)if(d[i]==0)add(0,i);
77     solve(0,0);
78     printf("%lld\n",dp[0][m]);
79     return 0;
80 }
T1

E. 太鼓达人

内存限制:128 MiB 时间限制:1000 ms 标准输入输出
题目类型:传统 评测方式:文本比较
 
题目描述

七夕祭上,Vani牵着cl的手,在明亮的灯光和欢乐的气氛中愉快地穿行。这时,在前面忽然出现了一台太鼓达人机台,而在机台前坐着的是刚刚被精英队伍成员XLk、Poet_shy和lydrainbowcat拯救出来的的applepi。看到两人对太鼓达人产生了兴趣,applepi果断闪人,于是cl拿起鼓棒准备挑战。然而即使是在普通难度下,cl的路人本性也充分地暴露了出来。一曲终了,不但没有过关,就连鼓都不灵了。Vani十分过意不去,决定帮助工作人员修鼓。

鼓的主要元件是M个围成一圈的传感器。每个传感器都有开和关两种工作状态,分别用1和0表示。显然,从不同的位置出发沿顺时针方向连续检查K个传感器可以得到M个长度为K的01串。Vani知道这M个01串应该是互不相同的。而且鼓的设计很精密,M会取到可能的最大值。现在Vani已经了解到了K的值,他希望你求出M的值,并给出字典序最小的传感器排布方案。

输入格式

一个整数K。

输出格式

一个整数M和一个二进制串,由一个空格分隔。表示可能的最大的M,以及字典序最小的排布方案,字符0表示关,1表示开。你输出的串的第一个字和最后一个字是相邻的。

样例
样例输入
3
样例输出
8 00010111

 

这题水题,爆搜就能A,其实打表也可以A,不用考虑复杂度问题,直接干!

爆搜:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int k,b[2050],jud[2050][2050],mas,cnt;
 5 bool v[2050],t[2050];
 6 void dfs(int x)
 7 {
 8     for(int i=0;i<=mas;i++)
 9         if(jud[x][i]&&!v[i])
10             jud[x][i]=0,
11             v[i]=1,dfs(i);
12     b[++cnt]=x;
13 }
14 int main()
15 {
16     scanf("%d",&k);
17     mas=(1<<k)-1;
18     //memset(jud,-1,sizeof(jud));
19     for(int i=0;i<=mas;i++)
20     {
21         int nt=(i<<1)&mas;
22         //cout<<nt;===next permutation;
23         t[nt|1]=1;t[nt]=0;
24         if((nt|1)!=i) jud[i][nt|1]=1;
25         if(nt!=i) jud[i][nt]=1;
26     }
27     dfs(0);
28     printf("%d ",mas+1);
29     for(int i=1;i<=k;i++) printf("0");
30     for(int i=cnt-1;i>k;i--) printf("%d",t[b[i]]);
31 }
爆搜

这里附赠lnc打表代码(默默的谴责!)

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n;
 5 int main()
 6 {
 7     scanf("%d",&n);
 8     if(n==2) puts("4 0011");
 9     if(n==3) puts("8 00010111");
10     if(n==4) puts("16 0000100110101111");
11     if(n==5) puts("32 00000100011001010011101011011111");
12     if(n==6) puts("64 0000001000011000101000111001001011001101001111010101110110111111");
13     if(n==7) puts("128 00000001000001100001010000111000100100010110001101000111100100110010101001011100110110011101001111101010110101111011011101111111");
14     if(n==8) puts("256 0000000010000001100000101000001110000100100001011000011010000111100010001001100010101000101110001100100011011000111010001111100100101001001110010101100101101001011110011001101010011011100111011001111010011111101010101110101101101011111011011110111011111111");
15     if(n==9) puts("512 00000000010000000110000001010000001110000010010000010110000011010000011110000100010000100110000101010000101110000110010000110110000111010000111110001000110001001010001001110001010010001010110001011010001011110001100110001101010001101110001110010001110110001111010001111110010010010110010011010010011110010100110010101010010101110010110110010111010010111110011001110011010110011011010011011110011101010011101110011110110011111010011111110101010110101011110101101110101110110101111110110110111110111011110111111111");
16     if(n==10) puts("1024 0000000000100000000110000000101000000011100000010010000001011000000110100000011110000010001000001001100000101010000010111000001100100000110110000011101000001111100001000010001100001001010000100111000010100100001010110000101101000010111100001100010000110011000011010100001101110000111001000011101100001111010000111111000100010100010001110001001001000100101100010011010001001111000101001100010101010001010111000101100100010110110001011101000101111100011000110010100011001110001101001000110101100011011010001101111000111001100011101010001110111000111100100011110110001111101000111111100100100110010010101001001011100100110110010011101001001111100101001010011100101010110010101101001010111100101100110010110101001011011100101110110010111101001011111100110011010011001111001101010100110101110011011011001101110100110111110011100111010110011101101001110111100111101010011110111001111101100111111010011111111010101010111010101101101010111110101101011011110101110111010111101101011111110110110111011011111101110111110111101111111111");
17     if(n==11) puts("2048 00000000000100000000011000000001010000000011100000001001000000010110000000110100000001111000000100010000001001100000010101000000101110000001100100000011011000000111010000001111100000100001000001000110000010010100000100111000001010010000010101100000101101000001011110000011000100000110011000001101010000011011100000111001000001110110000011110100000111111000010000110000100010100001000111000010010010000100101100001001101000010011110000101000100001010011000010101010000101011100001011001000010110110000101110100001011111000011000110000110010100001100111000011010010000110101100001101101000011011110000111000100001110011000011101010000111011100001111001000011110110000111110100001111111000100010010001000101100010001101000100011110001001001100010010101000100101110001001100100010011011000100111010001001111100010100011000101001010001010011100010101001000101010110001010110100010101111000101100110001011010100010110111000101110010001011101100010111101000101111110001100011100011001001000110010110001100110100011001111000110100110001101010100011010111000110110010001101101100011011101000110111110001110010100011100111000111010010001110101100011101101000111011110001111001100011110101000111101110001111100100011111011000111111010001111111100100100101001001001110010010101100100101101001001011110010011001100100110101001001101110010011101100100111101001001111110010100101100101001101001010011110010101001100101010101001010101110010101101100101011101001010111110010110011100101101011001011011010010110111100101110011001011101010010111011100101111011001011111010010111111100110011011001100111010011001111100110100111001101010110011010110100110101111001101101010011011011100110111011001101111010011011111100111001111001110101010011101011100111011011001110111010011101111100111101011001111011010011110111100111110101001111101110011111101100111111101001111111110101010101101010101111010101101110101011101101010111111010110101110101101101101011011111010111011110101111011101011111011010111111110110110111101101110111011011111110111011111101111011111011111111111");
18 }
打表过样例,暴力撵标算

G. 天天爱跑步

内存限制:512 MiB 时间限制:2000 ms 标准输入输出
题目类型:传统 评测方式:文本比较
 
题目描述

小 C 同学认为跑步非常有趣,于是决定制作一款叫做《天天爱跑步》的游戏。《天天爱跑步》是一个养成类游戏,需要玩家每天按时上线,完成打卡任务。

这个游戏的地图可以看作一棵包含 n n n 个结点和 n−1 n - 1 n1 条边的树,每条边连接两个结点,且任意两个结点存在一条路径互相可达。树上结点编号为从 1 1 1 到 n n n 的连续正整数。

现在有 m m m 个玩家,第 i i i 个玩家的起点为 Si S_i Si​​,终点为 Ti T_i Ti​​。每天打卡任务开始时,所有玩家在第 0 0 0 秒同时从自己的起点出发,以每秒跑一条边的速度,不间断地沿着最短路径向着自己的终点跑去,跑到终点后该玩家就算完成了打卡任务。(由于地图是一棵树,所以每个人的路径是唯一的)

小 C 想知道游戏的活跃度,所以在每个结点上都放置了一个观察员。在结点 j j j 的观察员会选择在第 Wj W_j Wj​​ 秒观察玩家,一个玩家能被这个观察员观察到当且仅当该玩家在第 Wj W_j Wj​​ 秒也正好到达了结点 j j j。小 C 想知道每个观察员会观察到多少人?

注意:我们认为一个玩家到达自己的终点后该玩家就会结束游戏,他不能等待一段时间后再被观察员观察到。即对于把结点 j j j 作为终点的玩家:若他在第 Wj W_j Wj​​ 秒前到达终点,则在结点 j j j 的观察员不能观察到该玩家;若他正好在第 Wj W_j Wj​​ 秒到达终点,则在结点 j j j 的观察员可以观察到这个玩家。

输入格式

第一行有两个整数 n n n 和 m m m。其中 n n n 代表树的结点数量,同时也是观察员的数量,m m m 代表玩家的数量。

接下来 n−1 n - 1 n1 行每行两个整数 u u u 和 v v v,表示结点 u u u 到结点 v v v 有一条边。

接下来一行 n n n 个整数,其中第 i i i 个整数为 Wi W_i Wi​​,表示结点 i i i 出现观察员的时间。

接下来 m m m 行,每行两个整数 Si S_i Si​​ 和 Ti T_i Ti​​,表示一个玩家的起点和终点。

对于所有的数据,保证 1≤Si,Ti≤n,0≤Wj≤n 1 \leq S_i, T_i \leq n, 0 \leq W_j \leq n 1Si​​,Ti​​n,0Wj​​n。

输出格式

输出一行 n n n 个整数,第 j j j 个整数表示结点 j j j 的观察员可以观察到多少人。

首先想的就是打v暴力,就是程序跟着人跑,但是按折磨跑,看一眼数据范围,一定TLE

然后就要转变思路,按着观察员跑程序,那么一个人对一个观察员在什么状态下可以有贡献呢?当然要:

把这个人要跑的路径分为s(起点)到lca(s,t);和lca到t(终点),然后上行和下行分别维护两个桶(装X写法,实际就是vector数组),用来统计,其实要注意的就是要去重,但我一开始并不知道,就卡了半天;还有就是,以后遇到这种题不要指望着暴力卡常可以ac,不存在的;

 

转载于:https://www.cnblogs.com/hzoi-lsc/p/11176107.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值