第十一周 11.9---11.15

---------11.9

补cf

cf 595 b

http://codeforces.com/contest/595/problem/B

比赛的时候不知道咋想的,以为是dp

去想c,半天不懂样例

后来写b,,,wa了一次后再改,,,,

后来改完过了,,,可是比赛早都结束了-------

貌似C题有问题,被移走了----

好笨啊-------

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int mod = 1e9+7;
 9 const int maxn = 1e5+5;
10 int a[maxn],b[maxn],l[maxn];
11 int n,k;
12 
13 int pow_my(int x){
14     int res = 1;
15     for(int i = 1;i <= x;i++) res = res*10;
16     return res;
17 }
18 
19 void solve(){
20     int c = 0,tmp;
21     memset(l,0,sizeof(l));
22     int x,y;
23     for(int i = 1;i <= n/k;i++){
24         if(b[i] != 0){
25             y = pow_my(k-1)-1;
26             tmp = y/a[i];
27             l[i] += tmp;
28            // printf("---tmp = %d\n",tmp);
29         }
30         x = pow_my(k-1);
31         y = pow_my(k)-1;
32         l[i] += y/a[i] - (x-1)/a[i];
33         if(b[i] != 0){
34             x = x*b[i]-1;
35             int yy = x+pow_my(k-1);
36             tmp = yy/a[i] - x/a[i];
37             l[i] -= tmp;
38             //printf("x = %d  yy = %d  tmp = %d\n",x,yy,tmp);
39         }
40 
41         if(b[i] != 0) l[i] += 1;
42         //printf("l[%d] = %d\n",i,l[i]);
43     }
44     long long  res = 1;
45     for(int i = 1;i <= n/k;i++){
46         res = (1LL*res*l[i])%mod;
47        // printf("l[%d=%d\n",i,l[i]);
48     }
49     printf("%I64d\n",res);
50 }
51 
52 int main(){
53     while(scanf("%d %d",&n,&k) != EOF){
54         for(int i = 1;i <= n/k;i++) scanf("%d",&a[i]);
55         for(int i = 1;i <= n/k;i++) scanf("%d",&b[i]);
56         solve();
57     }
58     return 0;
59 }
View Code

 

hdu 4003

给出一颗树,将 K 个机器人放在源点 S,问将整棵树遍历完的最小花费

树形dp  分组背包

没有思路,看的题解了

http://www.cnblogs.com/kuangbin/archive/2012/08/29/2661928.html

dp[i][j] 表示以 i 为根的子树 放 j 个机器人的最小花费

题解说对于每个节点,它的背包容量为 K,如果它有 i 个儿子,那么这一组有 i 个物品,每个物品的价值是 dp[i][0],dp[i][1],----dp[i][k],重量分别为 0,1,---,k

这里有点不理解----

我想的是 对于一组,放0个机器人,放1个机器人,放2个机器人,----,放k个机器人,分别是物品,然后重量分别是 0,1,2,,-----,k

啊-----还是没有懂啊---

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int INF = (1<<30)-1;
 9 int n,s,K;
10 const int maxn = 2e4+5;
11 int dp[maxn][15],first[maxn],ecnt;
12 
13 struct Edge{
14     int u,v,w,nxt;
15 }e[2*maxn];
16 
17 void Add_edges(int u,int v,int w){
18     e[ecnt].u = u;
19     e[ecnt].v = v;
20     e[ecnt].w = w;
21     e[ecnt].nxt = first[u];
22     first[u] = ecnt++;
23 }
24 
25 void dfs(int u,int fa){
26     for(int i = first[u];~i;i = e[i].nxt){
27         int v = e[i].v,w = e[i].w;
28         if(v == fa) continue;
29         dfs(v,u);
30         for(int  k = K;k >= 0;k--){
31             dp[u][k] += dp[v][0] + 2*w;
32             for(int j = 0;j <= k;j++)
33             dp[u][k] = min(dp[u][k],dp[u][k-j]+dp[v][j] + j*w);
34         }
35     }
36 }
37 
38 void solve(){
39     memset(dp,0,sizeof(dp));
40     dfs(s,-1);
41     printf("%d\n",dp[s][K]);
42 }
43 
44 int main(){
45     while(scanf("%d %d %d",&n,&s,&K) != EOF){
46         memset(first,-1,sizeof(first));
47         ecnt = 0;
48         for(int i = 1;i <= n-1;i++){
49             int u,v,w;
50             scanf("%d %d %d",&u,&v,&w);
51             Add_edges(u,v,w);
52             Add_edges(v,u,w);
53         }
54         solve();
55     }
56     return 0;
57 }
View Code

 

---------11.10

hdu 2415 & poj 3345

给出一颗树,每个节点都有一个代价,花了这个代价之后,就可以获得这个节点的子树包括这个节点的所有节点,问获得m个至少花多少钱

题解们都说的是很典型的树dp

还是想不出状态,,想到的就是到达一个节点u的时候,子节点 v 要不要取,然后记录个数------根本不对嘛

dp[i][j] 表示以 i 为根的子树取了j 个节点的最小花费

然后 dp[u][k] = min(dp[u][j],dp[u][k-j] + dp[v][j] )

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<map>
 6 #include<vector>
 7 using namespace std;
 8 
 9 const int maxn = 505;
10 int dp[maxn][maxn],sz[maxn],w[maxn];
11 int vis[maxn];
12 int n,m;
13 vector<int> g[maxn];
14 
15 void dfs(int u){
16     dp[u][0] = 0;
17     sz[u] = 1;
18     for(int i = 0;i < g[u].size();i++){
19         int v = g[u][i];
20        // printf("u = %d  v = %d\n",u,v);
21         dfs(v);
22         sz[u] += sz[v];
23         for(int k = sz[u];k >= 0;k--){
24             for(int j = 0;j <= k && j <= sz[v];j++){
25                 dp[u][k] = min(dp[u][k],dp[u][k-j] + dp[v][j]);
26             }
27         }
28     }
29     dp[u][sz[u]] = min(dp[u][sz[u]],w[u]);
30     return;
31 }
32 
33 int main(){
34     char s[105];
35     while(gets(s) && s[0] != '#' ){
36             int cnt = 0;
37             memset(w,0,sizeof(w));
38             sscanf(s,"%d%d",&n,&m);
39             for(int i = 0;i <= n;i++) g[i].clear();
40             map<string,int> h;
41             h.clear();
42             memset(vis,0,sizeof(vis));
43             for(int i = 1;i <= n;i++){
44                 scanf("%s",s);
45                 if(!h[s]){
46                     h[s] = ++cnt;
47                 }
48                 int u = h[s];
49                 int x;
50                 scanf("%d",&x);
51                 w[u] = x;
52                 while(getchar() != '\n'){
53                     scanf("%s",s);
54                     if(!h[s]){
55                         h[s] = ++cnt;
56                     }
57                     int v = h[s];
58                     vis[v] = 1;
59                     g[u].push_back(v);
60                 }
61             }
62             for(int i = 1;i <= n;i++){
63                 if(vis[i] == 0) {
64                     g[0].push_back(i);
65                 }
66             }
67             memset(sz,0,sizeof(sz));
68             w[0] = (1<<30)-1;
69             for(int i = 0;i < maxn;i++)
70                 for(int j = 0;j < maxn;j++) dp[i][j] = (1<<30)-1;
71             dfs(0);
72 
73             //for(int i = 0;i <= n;i++) printf("sz[%d] = %d\n",i,sz[i]);
74 
75             /*for(int i = 0;i <= n;i++){
76                 for(int j = 0;j <= m;j++){
77                     printf("dp[%d][%d] = %d\n",i,j,dp[i][j]);
78                 }
79             }
80 
81             for(int i = 0;i <= n;i++){
82                 printf("i = %d ",i);
83                 for(int j = 0;j < g[i].size();j++) printf("%d ",g[i][j]);
84                 printf("\n");
85             }*/
86 
87             int ans = (1<<30)-1;
88             for(int i = m;i <= n;i++) ans = min(ans,dp[0][i]);
89             printf("%d\n",ans);
90     }
91     return 0;
92 }
View Code

 

---------11.11

只补了一道题

 

---------11.12

看了一下 14年多校的第 7 场

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/4948885.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值