01背包问题:这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即c[i][v]表示前i件物品恰放入一个重量为m的背包可以获得的最大价值。则其状态转移方程便是:c[i][m]=max{c[i-1][m],c[i-1][m-w[i]]+p[i]}这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入重量为m的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为c[i- Read More
posted @ 2013-05-12 14:37 sidereal Views(162) Comments(0) Diggs(0)
只需在最长上升子序列中多加一个判断条件即可View Code 1 #include <iostream> 2 using namespace std; 3 double missile[1001]; 4 int dp[1001]; 5 int main() 6 { 7 int n; 8 while(1) 9 {10 cin>>n;11 if(n==0)12 break;13 for(int i=1;i<=n;i++)14 cin>>missile[i];15 ... Read More
posted @ 2012-10-21 22:00 sidereal Views(152) Comments(0) Diggs(0)
最长上升子序列先dp,O(n^2)太慢了,超时。10000的规模需要1千万,不可接受,5000000可以接受。View Code 1 #include <stdio.h> 2 3 int signal[40001]; 4 int length[40001]; 5 int main() 6 { 7 int test,p; 8 scanf("%d",&test); 9 for(int t=1;t<=test;t++){10 scanf("%d",&p);11 for(int i=1;i<=p;i++)12 scan.. Read More
posted @ 2012-10-21 20:59 sidereal Views(137) Comments(0) Diggs(0)
一维的dpView Code 1 #include <iostream> 2 #include <string> 3 using namespace std; 4 string dict[600]; 5 int dp[301]; 6 #define min(a,b) (a<b)?a:b 7 int main() 8 { 9 int W,L;10 int pd,pm;11 string msg;12 cin>>W>>L;13 cin>>msg;14 for(int i=0;i<W;i++)15 cin>>dict Read More
posted @ 2012-10-19 20:08 sidereal Views(137) Comments(0) Diggs(0)
这种循环的倒是第一次见View Code 1 #include <stdio.h> 2 3 int necklace[200]; 4 int m[101][101]; 5 int dp(int c[],int n) 6 { 7 for(int i=1;i<=2*n;i++) m[i][i]=0; 8 for(int r=2;r<=n;r++) 9 for(int i=1;i<2*n-r+1;i++){ //2n no value10 int j=i+r-1;11 m[i][j]=m[i+1][j]+c... Read More
posted @ 2012-10-19 20:06 sidereal Views(177) Comments(0) Diggs(0)
几乎与1753一样。不过flip的时候,多加了一个判断,居然就超时了。。。。。用位运算的方法特别好,flip的操作特别快。不过没做View Code 1 #include <stdio.h> 2 bool handlers[5][5]; //false means closed, true means open 3 bool isflip[5][5]={false}; 4 int step; 5 void flip(int row,int col) 6 { 7 int i; 8 handlers[row][col]=!handlers[row][col]; 9 ... Read More
posted @ 2012-10-13 20:26 sidereal Views(203) Comments(0) Diggs(0)
看成是一棵深度为16的树,每一个格子有两个状态,flip或non-flip,构成一棵二叉树。深搜这棵树就可以得到结果最少的轮数,可以给深搜加一条件: flip step次的时候,检查是否完成,step从0~16,这样就可以得到最少的轮数了。感觉可以用宽搜View Code 1 #include <stdio.h> 2 bool chess[5][5]; 3 int step; 4 void flip(int row,int col) 5 { 6 chess[row][col]=!chess[row][col]; 7 if(row-1>0) 8 chess[ro... Read More
posted @ 2012-10-13 19:44 sidereal Views(156) Comments(0) Diggs(0)
真是不知道为什么,枚举的时候明明没有枚举全啊!选定一个最小bandwidth之后,只枚举了一种情况,然后就进入下一个bandwidth的循环了。比如最小带宽为80,后面有两个数据(85,100,2)和(86,50,2),这个时候循环就只会去枚举(85,100,2),不会去枚举(86,50,2),为啥这样也能通过呢。。。。。 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 struct Device 6 { 7 int band Read More
posted @ 2012-10-13 15:34 sidereal Views(167) Comments(0) Diggs(0)
几经波折虽然写出了递归式,但是一提交,超时。然后改成了不用递归,先算出所有值,存到数组里,结果WA。然后发现,n=100时数太大太大,要用大数来处理。不想写大数的程序,所以改用java写,终于ACC++的两个版本:View Code 1 #include <stdio.h> 2 #include <string.h> 3 int connection[201]; 4 int connect(int m,int n) 5 { 6 if(n==m+1) 7 return 1; 8 if(m>=n) 9 return 1;10 //n>m+1... Read More
posted @ 2012-10-12 22:13 sidereal Views(257) Comments(0) Diggs(0)
测试数据没有问题的,但是不知为什么超时先转为后缀表达式,把括号去掉;再转为中缀表达式,转化成输出形式转化过程,想清楚了其实很简单 1 #include <string> 2 #include <iostream> 3 using namespace std; 4 int grade(char ch) 5 { 6 switch(ch) 7 { 8 case '*': 9 case '/': 10 return 2; 11 case '+': 12 case '-': 13 ... Read More
posted @ 2012-10-12 20:41 sidereal Views(241) Comments(0) Diggs(0)