---------11.9
补cf
cf 595 b
http://codeforces.com/contest/595/problem/B
比赛的时候不知道咋想的,以为是dp
去想c,半天不懂样例
后来写b,,,wa了一次后再改,,,,
后来改完过了,,,可是比赛早都结束了-------
貌似C题有问题,被移走了----
好笨啊-------
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
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
啊-----还是没有懂啊---
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
---------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] )
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
---------11.11
只补了一道题
---------11.12
看了一下 14年多校的第 7 场