这道题的DP思想还是挺巧妙的。
毫无疑问要先对w排序,然后将所有组的DP记录都置1,再依次填表。
当前序号 | w | s | DP记录 | 原先的序号 |
0 | 500 | 2000 | 1 | 2 |
1 | 1000 | 4000 | 1 | 3 |
2 | 1100 | 3000 | 2 | 4 |
3 | 2000 | 1900 | 3 | 8 |
4 | 6000 | 2000 | 3 | 8 |
5 | 6000 | 1200 | 4 | 7 |
6 | 6000 | 2100 | 3 | 1 |
7 | 6008 | 1300 | 4 | 0 |
8 | 8000 | 1400 | 4 | 6 |
主要是第三行,举个例子:
6000 1200那组,在这组前面的组中当前序号为0、1、2、3、4中的s值都比1200大,那么就取DP记录最大一组加上1,如果没有比它大的就不做。
填完表后再从后往前打印出结果就OK了。
Accepted | 1108 | C | 00:00.00 | 432K |
#include <stdlib.h>
struct s
{
int w;
int s;
int index;
int rd;
}read[1000 ];
int cmp(const void* a,const void* b)
{
return (*(struct s*)a).w-(*(struct s* )b).w;
}
void solve()
{
int i,j,cnt = 0,max = 0,temp = 0,res[1000 ];
memset(res,0,sizeof (res));
while(scanf("%d%d",&read[cnt].w,&read[cnt].s) != EOF)
{
read[cnt].index = cnt;
cnt++ ;
}
cnt;
qsort(read,cnt,sizeof(read[0 ]),cmp);
for(i = 0; i < cnt; i++ )
{
read[i].rd = 1 ;
for(j = 0; j < i; j++ )
{
if(read[i].s < read[j].s)
{
read[i].rd = read[i].rd < read[j].rd + 1 ? read[j].rd + 1 : read[i].rd;
max = max > read[i].rd ? max : read[i].rd;
}
}
}
printf("%d/n" ,max);
for(i = cnt - 1; i > 0; i-- )
{
if(read[i].rd == max)
{
if(temp == 0 || read[temp].s < read[i].s)
{
temp = i;
max-- ;
res[max] = read[i].index + 1 ;
}
}
}
i = 0 ;
while(res[i] != 0 )
printf("%d/n",res[i++ ]);
}
void main()
{
#ifndef ONLINE_JUDGE
freopen("test.txt","r",stdin);
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
}