zoukankan      html  css  js  c++  java
  • 4月11日

    poj3616

    题意:奶牛在1到n时间段内产奶,总共有m个产奶区间,买个区间有开始时间和结束时间,还有产奶量,同时每次产完奶需要休息一定的时间,求最大产奶量

    分析:比较简单的dp,有点像最长上升子序列的变种,把产奶时间按开始时间排序,对于开始时间大于前面结束时间的点,求其最大的产奶量

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=1500;
    15 int dp[maxn];
    16 typedef struct p
    17 {
    18     int start,over,value;
    19 }p;
    20 int n,m,r;
    21 bool cmp(p a,p b)
    22 {
    23     return a.start<b.start;
    24 }
    25 int main()
    26 {
    27     while(cin>>n>>m>>r)
    28     {
    29         p s[maxn];
    30         for(int i=0;i<m;i++)
    31         {
    32             cin>>s[i].start>>s[i].over>>s[i].value;
    33             s[i].over+=r;
    34         }
    35         sort(s,s+m,cmp);
    36         memset(dp,0,sizeof(dp));
    37         for(int i=0;i<m;i++)
    38         {
    39             dp[i]=s[i].value;
    40             for(int j=0;j<i;j++){
    41                 if(s[i].start>=s[j].over)
    42                     dp[i]=max(dp[i],dp[j]+s[i].value);
    43             }
    44         }
    45         int mx=0;
    46         for(int i=0;i<m;i++)
    47             mx=max(mx,dp[i]);
    48         cout<<mx<<endl;
    49     }
    50     return 0;
    51 }
    View Code

    有关划分数的问题:

    n个无区别的物体,划分成不超过m组,求划分方法数。

    分析:这个问题被称为n的m划分。设n的m划分是ai,(i=1.....m)(a1+a2+...+am=n),若没个ai>0,则{ai-1}对应n-m的m划分。若存在ai=0,则对应了n的m-1划分。令dp[i][j]为j的i划分,dp[i][j]=dp[i-1][j]+dp[i][j-i];

     1 int dp[maxn][maxn];
     2 void solve()
     3 {
     4     dp[0][0]=1;
     5     for(int i=1;i<=m;i++){
     6         for(int j=0;j<=n;j++)
     7         {
     8             if(j-i>=0)
     9                 dp[i][j]=dp[i-1][j]+dp[i][j-i];
    10             else
    11                 dp[i][j]=dp[i-1][j];
    12         }
    13     }
    14 }
    View Code

     poj3280(区间dp)

    题意:可以在任意位置增删字符,增删有不同代价,求能构成回文串的最小代价,题解说是取的是增加和删除的最小代价

    分析:dp[i][j]表示i到j构成回文串的最小代价,如果s[i]=s[j],那么dp[i][j]=dp[i+1][j-1],若不想等,我们知道对于任何一个区间,增加和删除一个字符都不会对原有区间产生影响,所以只用求dp[i+1][j]和dp[i][j-1]当中的最小值即可。非常感谢夹克爷给我的耐心讲解,开始还不太理解这题

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=2020;
    15 int dp[maxn][maxn];
    16 char s[maxn];
    17 int n,m;
    18 int vis[30];
    19 int main()
    20 {
    21     while(cin>>n>>m)
    22     {
    23         cin>>s;
    24         memset(dp,0,sizeof(dp));
    25         memset(vis,0,sizeof(vis));
    26         for(int i=0;i<n;i++)
    27         {
    28             char c;
    29             int start,over;
    30             cin>>c>>start>>over;
    31             vis[c-'a']=min(start,over);
    32         }
    33         for(int i=m-1;i>=0;i--)
    34         {
    35             for(int j=i+1;j<m;j++)
    36             {
    37                 if(s[i]==s[j])
    38                     dp[i][j]=dp[i+1][j-1];
    39                 else
    40                     dp[i][j]=min(dp[i+1][j]+vis[s[i]-'a'],dp[i][j-1]+vis[s[j]-'a']);
    41             }
    42         }
    43         cout<<dp[0][m-1]<<endl;
    44     }
    45     return 0;
    46 }
    View Code

     51nod 1092(区间dp)

    最后再来一道一样的题目,不过更为简单,求最小添加多少字符可以构成回文串

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=1010;
    15 char s[maxn];
    16 int dp[maxn][maxn];
    17 int n;
    18 int main()
    19 {
    20     while(cin>>s)
    21     {
    22         memset(dp,0,sizeof(dp));
    23         n=strlen(s);
    24         for(int i=n-1;i>=0;i--)
    25         {
    26             for(int j=i+1;j<n;j++)
    27             {
    28                 if(s[i]==s[j])
    29                     dp[i][j]=dp[i+1][j-1];
    30                 else
    31                     dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1;
    32             }
    33         }
    34         cout<<dp[0][n-1]<<endl;
    35     }
    36     return 0;
    37 }
    View Code
  • 相关阅读:
    .Net培训个人总结笔记1
    .Net培训个人总结笔记0——前言
    python访问数据库
    默认构造函数
    VC使用中一些常见问题
    使用VC进行调试
    sqlite3.OperationalError: Could not decode to UTF8 column XXX with text '***'
    cent os 5.5 安装
    initialization of xxx is skipped by xxx
    VC程序启动时隐藏主窗口
  • 原文地址:https://www.cnblogs.com/wolf940509/p/5377479.html
Copyright © 2011-2022 走看看