2015 Multi-University Training Contest 9 hdu 5396 Expression
2015-08-19 12:01
148 查看
题意:一个表达式,加不同的括号得到不同的计算顺序,只要有一个计算顺序不同这两个表达式就是不同的。求所有表达式的和。
区间dp +排列组合
一开始我就知道大概可以用区间dp解决,开个二维记录区间[l,r]的所有方案的总和,然后枚举最后一次操作的符号,把每个区间分为两半,因为左边区间的总和可能有几种情况相加而得到a1,a2,a3,我们把其和保存在数组d【l】【k】,k是枚举的,代表最后操作符号的位置,因为原区间【l】【r】的dp值涉及到每个两个小区间【l】【k】、【k+1】【r】的方案数。例如
A(a,b,c) + B(d,e)
由于我们要求每种可能
那么将产生
a+db+dc+d
a+eb+ec+e
可以发现其等价于 2A + 3B A里面的元素都加了两次,B里面的元素都加了3次
转:http://blog.csdn.net/corncsd/article/details/47758975
dp[l][r]的计算方法是枚举最后一个被计算的位置i,设n1=dp[l][i],n2=dp[i+1][r],t1=t[l][i],t2=t[i+1][r]。那么对于加号,对于每个i要加上n1*t2+n2*t1,对于右边不同的组合,左边的数每次都要被加一次,同理左边不同的组合,右边的数每次也要被加一次。因此n1被加了t2次,n2被加了t1次。减法和加法一样。乘法是直接n1*n2。
当时忘记下面的了。。。。。。。
这还没完,注意就算是左边的顺序和右边的顺序的确定,假设左边有f1个符号,右边有f2个符号,也有C[f1+f2][f1]种排法,相当于在f1+f2个位置中选f1个,剩下的给f2,f1和f2中排列的相对顺序不改变,所以还要乘上C[f1+f2][f1]。同理对于每个i,t[l][r]要加上t1*t2*C[f1+f2][f1]。
其实
区间dp +排列组合
一开始我就知道大概可以用区间dp解决,开个二维记录区间[l,r]的所有方案的总和,然后枚举最后一次操作的符号,把每个区间分为两半,因为左边区间的总和可能有几种情况相加而得到a1,a2,a3,我们把其和保存在数组d【l】【k】,k是枚举的,代表最后操作符号的位置,因为原区间【l】【r】的dp值涉及到每个两个小区间【l】【k】、【k+1】【r】的方案数。例如A(a,b,c) + B(d,e)
由于我们要求每种可能
那么将产生
a+db+dc+d
a+eb+ec+e
可以发现其等价于 2A + 3B A里面的元素都加了两次,B里面的元素都加了3次
转:http://blog.csdn.net/corncsd/article/details/47758975
dp[l][r]的计算方法是枚举最后一个被计算的位置i,设n1=dp[l][i],n2=dp[i+1][r],t1=t[l][i],t2=t[i+1][r]。那么对于加号,对于每个i要加上n1*t2+n2*t1,对于右边不同的组合,左边的数每次都要被加一次,同理左边不同的组合,右边的数每次也要被加一次。因此n1被加了t2次,n2被加了t1次。减法和加法一样。乘法是直接n1*n2。
当时忘记下面的了。。。。。。。
这还没完,注意就算是左边的顺序和右边的顺序的确定,假设左边有f1个符号,右边有f2个符号,也有C[f1+f2][f1]种排法,相当于在f1+f2个位置中选f1个,剩下的给f2,f1和f2中排列的相对顺序不改变,所以还要乘上C[f1+f2][f1]。同理对于每个i,t[l][r]要加上t1*t2*C[f1+f2][f1]。
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<algorithm> int inf= 1<<30; int v[110]; int w[110]; int d[102][1100][33]; using namespace std; int main() { int i,j,k,n,m,T,K,N,V,m1,m2,t; scanf("%d",&T); while(T--) { scanf("%d%d%d",&N,&V,&K); for(i=0;i<=N;i++){ for(j=0;j<=V;j++){ for(k=1;k<=30;k++) { d[i][j][k]=-inf; } } } for(i=1;i<=N;i++) scanf("%d",&w[i]); for(i=1;i<=N;i++) scanf("%d",&v[i]); for(j=V;j>=0;j--) { if(j>=v[i]) d[1][j][1]=w[1]; else d[1][j][1]=0; } for(i=2;i<=N;i++) { for(j=V;j>=1;j--) { m1=m2=1; for(k=1;k<=K;k++) { t=d[i-1][j][m1]; if(j>=v[i]&&d[i-1][j][m1]<d[i-1][j-v[i]][m2]+w[i]) { t=d[i-1][j-v[i]][m2]+w[i]; m2++; } else m1++; d[i][j][k]=t; } } } int ans=d [V][K]; if(ans<0) ans=0; printf("%d\n",ans); } return 0; }
其实
相关文章推荐
- codeforces 519C C. A and B and Team Training(枚举)
- 2015 HUAS Summer Trainning #6~O
- HDU 1302 The Snail
- 出现( linker command failed with exit code 1)错误总结
- 如何搞定foxmail下的.eml文件导入到win7内的outlook2007
- jboss eap 6.3 域(Domain)模式配置
- XML 包含函数fn:contains(string1,string2)的用法
- 华为OJ(Redraiment的走法)
- 【android学习笔记】理解android.intent.action.MAIN 与 android.intent.category.LAUNCHER
- 2015 Multi-University Training Contest 9-1007 Travelling Salesman Problem
- Communications link failure Last packet sent to the server was 0 ms ago.问题解决
- HDU 5402 Travelling Salesman Problem (2015 Multi-University Training Contest 9 2015多校联合)
- Aisen新浪微博客户端项目源码
- tools:context=".MainActivity的作用
- HDU 5405 Sometimes Naive 2015多校联合训练赛#9 LCT 树链剖分
- 马尔可夫链及吉布斯抽样 入门详解(Markov Chain Monte Carlo and Gibbs Sampling)
- 再谈应用环境下的TIME_WAIT和CLOSE_WAIT
- 2015 HUAS Summer Trainning #6~I
- Contain Duplicate III*******
- Contain Duplicate II