poj_2533_Longest Ordered Su... poj_1260_Pearls hdu_1025_Constructing Roa... poj_2533_Longest Ordered

来源:互联网 发布:易推客营销软件下载 编辑:程序博客网 时间:2024/05/16 19:34

/*

标题不能太长,所以写这了

poj_2533_Longest Ordered Subsequence poj_1260_Pearls hdu_1025_Constructing Roads In JGShining's King hdu_1074_Doing Homework

*/

poj_2533_Longest Ordered Subsequence

http://poj.org/problem?id=2533

LIS 不解释 ==

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int main(){int n;cin>>n;int a[1010];int dp[1010];for (int i=0;i<n;i++){cin>>a[i];}int ans=1;for (int i=0;i<n;i++){dp[i]=1;for (int j=0;j<i;j++){if(a[i]>a[j]){dp[i]=max(dp[i],dp[j]+1);}}ans=max(ans,dp[i]);}cout<<ans<<endl;}
poj_1260_Pearls

http://poj.org/problem?id=1260

有n种珍珠,价额越高,质量越好,购买时每种应付款(数量+10)*单价;

原计划n种珍珠,第i种买ai颗,价格pi;(价p i>p i-1)

现在需要求换种方案,使得购买的数量不变,且质量更好,总价更小,求总价。

价格更少的关键在于那个“+10”,

此外,替换珍珠是连续的一个段,如果第i+2种珍珠可以用来替换第i种,那么第i+1应该更便意。

so dp[i] = min ( dp[i] , dp[j] +(sum[i] - sum[j] + 10) * p[i] );

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int INF=999999999;struct Node {int a,p;}node[106];bool cmp (Node a,Node b){return  a.p<b.p;}int main(){    int c;    cin>>c;    while (c--){        int n,sum=0;        int dp[106];        int s[106];        dp[0]=0;s[0]=0;        cin>>n;        for (int i=1;i<=n;i++){            cin>>node[i].a>>node[i].p;            sum+=(node[i].a+10)*node[i].p;            s[i]=s[i-1]+node[i].a;        }        sort(node,node+n,cmp);        for (int i=1;i<=n;i++){        dp[i]=INF;            for (int j=0;j<=i-1;j++){            dp[i]=min(dp[i],dp[j]+(s[i]-s[j]+10)*node[i].p);            }            // cout<<dp[i]<<" ";        }        cout<<dp[n]<<endl;    }    return 0;}

hdu_1025_Constructing Roads In JGShining's King

http://acm.hdu.edu.cn/showproblem.php?pid=1025

平行线上有一些城市,一边是富饶的,一边是贫困的。没坐父老的城市拥有一种资源,对应着有一座贫困的城市缺少改资源。

现在The King 希望修通富饶城市和贫困城市之间的马路来帮助他们(资源的拥有和缺少必须对应),但为了防止交通事故,不允许两条道路相交叉。

问最多修多少道路。

以贫困城市为数组下标,富饶城市为数组元素的值,求 LIS 。

==  题目好坑,O(nlogn)的方法猜不会TLE,(copy自白书)而且,road和roads啊啊啊啊啊==

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int n;const int INF=999999999;int dp[500050];int main(){    int c(0);    char road[2][10]={"road","roads"};    while (scanf("%d",&n)!=EOF){        int a[500050];        for (int i=0;i<n;i++){            int x,y;            scanf ("%d%d",&x,&y);            a[x-1]=y;        }        fill (dp,dp+n,INF);        for (int i=0;i<n;i++){            *lower_bound(dp,dp+n,a[i])=a[i];        }        int ans=lower_bound(dp,dp+n,INF)-dp;;        printf ("Case %d:\nMy king, at most %d %s can be built.\n",++c,ans,road[ans!=1?1:0]);    }    return 0;}

hdu_1074_Doing Homework

http://acm.hdu.edu.cn/showproblem.php?pid=1074

给出n份作业的截止时间第 D 天和需要花费时间 C 天,没迟交一天扣一分。

开这题好几天了,一直没思路,虽然知道是状压dp,知道今天中午吃饭的时候才来灵感,用一维的dp。T^T,一直在想二维的。

把n份作业的做与没做压缩成一个二进制的 int 。第i位表示第i份作业有没有做。

如果s表示做完的集合,那么他可以由 {s}-{j} V {j} 得到。

 dp[s] = min( dp[s-(1<<j)] + s); ( s : 做第j份作业要罚的分,s = max( t[s] + Cs - Ds , 0 ) );

路径还原:fa 数组记录由状态 fa[ i ]得到状态 i ;还原是用位运算加递归;

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define INF 999999999struct Work {string s;int d,c;}w[16];struct Node{int p,t;};int  fa[1<<15+6];Node dp[1<<15+6];void findway (int a,int b){int c=a-b;int k=0;while(c!=1){c>>=1;k++;}cout<<w[k].s<<endl;}void find (int f,int k){if (f!=k){find (fa[f],f);findway(k,f);}}int main(){int c;cin>>c;while (c--){int n;scanf("%d",&n);for (int i=0;i<n;i++){cin>>w[i].s>>w[i].d>>w[i].c;}for (int i=0;i<(1<<n);i++){dp[i].p=INF;dp[i].t=0;fa[i]=i;}dp[0].p=0;for (int i=1;i<(1<<n);i++){for (int j=0;j<n;j++){if (i&(1<<j)){int s;s=max(dp[i-(1<<j)].t+w[j].c-w[j].d,0);if(dp[i].p>=dp[i-(1<<j)].p+s){dp[i].p=dp[i-(1<<j)].p+s;fa[i]=i-(1<<j);}dp[i].t=dp[i-(1<<j)].t+w[j].c;}}}printf ("%d\n",dp[(1<<n)-1]);int k=(1<<n)-1;find(fa[k],k);}return 0;}

dp水我水的好欢快啊~啊。


0 0
原创粉丝点击