摘要:
二次dp,还算好想。先第一遍dp找出最后一个数字最小是几。dpf[i]=max{j}+1(dpf[j],dpf[j]+1,…,j位组成的数字小于j+1,j+2,…,i位组成的数字。在第二遍dp,找出第一个数字最大是几。dpb[i]=max{j}(I,i+1,…,j为组成的数字小于j+1,j+2,…,dpb[i+2]位组成的数字。按轨迹输出。!记住:每次都要将两个数组清零!(坑了我半天)代码:#include#includeusing namespace std;int dpf[90]={0},dpb[90]={0};char a[90];int max(int x,int y){ return 阅读全文
摘要:
此题亦一眼看出算法,一次AC。没什么好讲的,就是一个普通的树形动规。用dp[n][0]表示n号顶点不取时的最大值,dp[n][1]表示n号顶点取时的最大值。dp[n][0]=max{dp[x][0],dp[x][1]}(x is son of n)dp[n][1]=max{sigma(x1,x2,…,xk)}(x1,x2,…,xk are k sons of n)本来能写O(n)的算法,偷懒写了O(n^2)的算法,也能AC优化:用邻接链表,O(n)(我没用)代码:#include#includeusing namespace std;int n,x[1001],y[1001],fa[1001] 阅读全文
摘要:
很高兴,这道题刚编译成功提交就AC了。简单的多重背包,标算估计是5、6维动规。其实可以通过6进制压成一维。判定是一个特价方式是否可行只需自己推一下就行了,很简单(对应位上的数目标不小于特价所需条件)。代码:#includeusing namespace std;int t[10],map[1000],l[10],c[120],p[120],dp[300000];void init(){ t[0]=1; for(int i=1;iy)return 0; for(int i=9;i>=0;i--){ if(x/t[i]>y/t[i])return 0; x%=t[i],y%=t[i]; 阅读全文
摘要:
简单的dp忘了\n,调了半天(目测不是第一次了)直接贴代码:#include#includeusing namespace std;char s[120];int dp[120][120]={0};int min(int x,int y){ return (x>y)?y:x;}void solve(int x,int y){ if(dp[x][y]==0){ for(int i=x;i<=y;i++) printf("%c",s[i]); return; } if(y==x){ if(s[x]=='(' || s[x]==')') 阅读全文
摘要:
昨天晚上看的题。说实话,我一眼就看出了是二分图,再一眼就看出了是二分图+dp(01背包)。但悲剧的是我一眼看出的算法是正确的,但我总以为它是错误的,浪费了很长时间像其他算法(TAT)。今天终于把代码打了出来,刚开始01背包的优化后来发现是错误的,忘记删了,导致WA一次。吃晚饭时突然发现了,便AC。2013-6-29代码:#include#includeusing namespace std;int n,col[101],w[202],m=0,dp[101][101],pre[101][101];bool map[101][101]={0},vis[202]={0},f=0;void dfs(i 阅读全文