HDU中的DP---动态规划

//Made by syx
//Time 2010年8月15日 10:13:12
//
//


小结:DP的基本思想
如果各个子问题不是独立的,不同的子问题的个数只是多项式量级,
如果我们能够保存已经解决的子问题的答案,而在需要的时候再找
出已求得的答案,这样就可以避免大量的重复计算。
   由此而来的基本思路是——用一个表记录所有已解决的子
问题的答案,不管该问题以后是否被用到,只要它被计算过,就将
其结果填入表中。


/*
//1421 搬寝室

#include  
#include
#define size 2005
#define INIT 2147483646

int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}

int Min(int a,int b)
{
return a}

int dp[size][1005];

int main()
{
int n,k,i,j;
int val[size] = { 0};
dp[0][0] = 0;
while (scanf("%d%d",&n,&k)!=EOF)
{
val[0] = 0;
for(i=1;i<=n;i++)
scanf("%d",&val[i]);
qsort(val+1,n,sizeof(val[0]),cmp);
for (i=0;i<=n;i++)
{
for(j=1;j<=k;j++)
dp[i][j] = INIT;
}
for (i=2;i<=n;i++)
{
for (j=1;j*2<=i;j++)
dp[i][j] = Min(dp[i-2][j-1]+(val[i]-val[i-1])*(val[i]-val[i-1]),dp[i-1][j]);
}
printf("%d\n",dp[n][k]);
}
return 0;
}

*/


/*
//1159
//最长公共子序列问题

#include 
#include <string>
using namespace std;
int max(int a,int b)
{
return a >= b ? a : b;
}

int a[1000][1000];
int main()
{
int i , j;
//int a[1000][1000];
string s1,s2;
while(cin>>s1>>s2)
{
memset(a[0],0,100);
for(i=0; ifor(j=0; j {
if(s1[i] == s2[j] )
a[i+1][j+1] = a[i-1+1][j-1+1] + 1;
else
a[i+1][j+1] = max(a[i-1+1][j+1] , a[i+1][j-1+1]);
}
cout<}
return 0;
}

*/

/*
//1087
//题目就是求在一个有序的序列(从小到大)中求一个和最大的序列,所以
//也是最长序列的扩展

//

#include
#include
using namespace std;
int dp[1001];
int num[1001];
int max(int a,int b)
{
return a>=b?a:b;
}
int main()
{
int i,j,n;
for(;cin>>n&&n;)
{
memset(dp,0,sizeof dp);
for( i=1;i<=n;i++)
{
cin>>num[i];
}
int maxdp=0;
for( i=1;i<=n;i++)
for( j=0;jif(num[i]>num[j])
{
dp[i]=max(dp[i],dp[j]+num[i]);
if(dp[i]>maxdp)
maxdp=dp[i];
}
cout< }
return 0;
}

*/

/*
//1160
//题目大意:所有的老鼠都有一个重量(W) 和一个速度(S),要求找出满足以下关系的最长序列
//W[m[1]] < W[m[2]] < ... < W[m[n]]
//and
//S[m[1]] > S[m[2]] > ... > S[m[n]]
//因为是一个二维的关系,处理起来比较麻烦,所以,我们可以先选择对重量进行从小到大排序(也可以选速度),这样,就只需找出以为上的最长上升子序列了。
//状态转移方程
//    if (a[j].s>a[i].s && m[j]+1>m[i])
//    {
//     m[i]=m[j]+1;
//     pre[i]=j;
//    }
//不过题目最后要的输出是最长上升子序列的长度 以及该子序列选取的所有老鼠的编号(从1开始的)
//刚开始怎么调试,得出的答案都和Sample Output不是很一样,郁闷了很久

#include 
#include
struct No
{
int w;
int s;
int num;
}a[1005];
int cmp(const void *c,const void *d)
{
return *(int *)c-*(int *)d;
}
int main ()
{
int n=0,i,j,k,max;
int m[1005],pre[1005],p[1005];
while (scanf("%d %d",&a[n].w,&a[n].s)!=EOF)
{
a[n].num=n+1;
n++;
}
qsort(a,n,sizeof(a[0]),cmp);
for (i=0;i{
m[i]=1;pre[i]=-1;
for (j=i-1;j>=0;j--)
{
if (a[j].s>a[i].s && m[j]+1>m[i])
{
m[i]=m[j]+1;
pre[i]=j;
}
}
}
for (max=0,i=0;iif (m[i]>m[max]) max=i;
printf("%d\n",m[max]);
k=0;
while (pre[max]!=-1)
{
p[k++]=a[max].num;
max=pre[max];
}
p[k++]=a[max].num;
while (k--)
printf ("%d\n",p[k]);
return 0;
}

*/

/*
//1160

#include  
#include
#include
#include
#define MAX 1000
using namespace std;
struct Mouse
{
int W;
int S;
int L;
};
Mouse mouse[MAX+10];
int flag[MAX+10];
int f[MAX+10];
bool cmp(const Mouse a,const Mouse b)
{
if(a.W==b.W) return a.S>b.S;
return a.W}
int main()
{
int i(1),j,n,w,s;
stack<int> stk;
f[1]=1;
flag[1]=1;
while(scanf("%d%d",&w,&s)!=EOF)
{
mouse[i].W=w;
mouse[i].S=s;
mouse[i].L=i;
i++;
}
n=i;
sort(mouse+1,mouse+n,cmp);
for(i=2;i {
int temp(0);
for(j=1;j {
if(mouse[j].Wmouse[i].S&&f[j]>temp)
{
temp=f[j];
flag[i]=j;
}
f[i]=temp+1;
}
}
int max=-1,maxi;
for(i=1;iif(max {
max=f[i];
maxi=i;
}
printf("%d\n",max);
for(i=0;i{
int j=maxi;
stk.push(mouse[j].L);
maxi=flag[j];
}
while(!stk.empty())
{
printf("%d\n",stk.top());
stk.pop();
}
return 0;
}

*/

/*
//最长有序子序列

#include 
int main()
{
int a[9] = { 1,4,7,2,5,8,3,6,9};
int f[9] = { 1};//保存最长子序列,第一个是1
int i,j;
for(i=1; i<9; i++)
{
for(j=i-1; j>=0; j--)
{
if(a[i]>=a[j])
{
f[i] = f[j] + 1;
break;
}
}
}
for(i=0; i<9; i++)
{
printf("%d ",f[i]);
}
return 0;
}

*/
/*
//数塔问题

#include  
#define maxn 100
using namespace std;
int max(int a,int b)
{
return (a>b?a:b);
}
int main()
{
int a[maxn+1][maxn+1],i,j,n;
cin >>n;
for (i=1;i<=n;i++)
for (j=1;j<=i;j++)
cin >>a[i][j];
for (i=n-1;i>=1;i--)
for (j=1;j<=i;j++)
a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
cout <1][1]<return 0;
}

*/

你可能感兴趣的:(数据结构与算法)