跟金保学DP系列の一
2015-08-03 09:44
246 查看
A:Ingenuous Cubrency
分析:硬币兑换问题,直接背包
B:Partial Teacher
分析:我们对于每一个位置要判断1:后面以它最大,2:前面它最小,复杂度O(n^2)
C:Porcelain
分析:看到这道题我的内心是崩溃的,因为m太TM大了,但是事实证明我太年轻了
显然我们要预处理每行取k个的最大值,这个复杂度约为(O(N^3))
然后就是背包dp[i][j]:前i行选j个的最大价值,复杂度约(O(N^2*M))最大情况下达1e8
D:Eternal Victory
分析:开始题意没读清楚,给你n个点,n-1条边,每个点还必须走到,问你最小代价
这道题就是和FZU月赛题目一样的,求个最长路,然后总价值*2-最大价值的路
分析:硬币兑换问题,直接背包
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=1e5+100; int tot=0; int v[110]; LL dp[11000]; void init() { for(int i=1;i*i*i<=10000;i++) v[tot++]=i*i*i; } int main() { init(); int n; while(~scanf("%d",&n)) { CLEAR(dp,0); dp[0]=1; for(int i=0;i<tot;i++) for(int j=v[i];j<=n;j++) dp[j]+=dp[j-v[i]]; printf("%lld\n",dp ); } return 0; }
B:Partial Teacher
分析:我们对于每一个位置要判断1:后面以它最大,2:前面它最小,复杂度O(n^2)
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=1e5+100; int dp[maxn]; char str[maxn]; int n; void solve() { for(int i=0;i<n-1;i++) { int l=1,r=1; int pos1=i-1,pos2=i; while(pos1>=0&&str[pos1]!='L') { if(str[pos1]=='R') r++; pos1--; } while(pos2<n-1&&str[pos2]!='R') { if(str[pos2]=='L') l++; pos2++; } dp[i]=max(l,r); } if(str[n-2]=='R') dp[n-1]=dp[n-2]+1; else if(str[n-2]=='L') dp[n-1]=1; else dp[n-1]=dp[n-2]; } int main() { while(~scanf("%d",&n)) { scanf("%s",str); solve(); for(int i=0;i<n;i++) printf(i==n-1?"%d\n":"%d ",dp[i]); } return 0; }
C:Porcelain
分析:看到这道题我的内心是崩溃的,因为m太TM大了,但是事实证明我太年轻了
显然我们要预处理每行取k个的最大值,这个复杂度约为(O(N^3))
然后就是背包dp[i][j]:前i行选j个的最大价值,复杂度约(O(N^2*M))最大情况下达1e8
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=1e5+100; int n,m; int k,x,all,a[110],num[110]; int dp[110][110],mx[110]; int sum[110][110]; int d[110][10005]; int dfs(int l,int r,int s) { if(l>r) return 0; if(dp[l][r]!=-1) return dp[l][r]; int ans=INF; if(l<=r) ans=min(ans,dfs(l+1,r,s+1)+a[l]); if(l<=r) ans=min(ans,dfs(l,r-1,s+1)+a[r]); mx[s]=max(mx[s],all-ans); return dp[l][r]=ans; } int main() { while(~scanf("%d%d",&n,&m)) { REPF(i,1,n) { CLEAR(dp,-1); CLEAR(mx,0); all=0; scanf("%d",&k); num[i]=k; REPF(j,1,k) { scanf("%d",&a[j]); all+=a[j]; } dfs(1,k,0); mx[k]=all; REPF(j,1,k) sum[i][j]=mx[j]; } CLEAR(d,0); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int k=0;k<=num[i];k++) { if(k>j) continue; d[i][j]=max(d[i-1][j-k]+sum[i][k],d[i][j]); } } } printf("%d\n",d [m]); } return 0; }
D:Eternal Victory
分析:开始题意没读清楚,给你n个点,n-1条边,每个点还必须走到,问你最小代价
这道题就是和FZU月赛题目一样的,求个最长路,然后总价值*2-最大价值的路
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=1e5+100; struct node{ int to,w; int next; }e[maxn<<2]; int tot,n; LL all,sum; int head[maxn],vis[maxn]; void addedge(int u,int v,int w) { e[tot].to=v;e[tot].next=head[u];e[tot].w=w; head[u]=tot++; } void dfs(int u,LL s) { sum=max(sum,s); vis[u]=1; for(int i=head[u];i!=-1;i=e[i].next) { int to=e[i].to; if(!vis[to]) dfs(to,s+e[i].w); } } int main() { int x,y,w; while(~scanf("%d",&n)) { int tot=0; all=sum=0; CLEAR(head,-1); CLEAR(vis,0); REPF(i,1,n-1) { scanf("%d%d%d",&x,&y,&w); addedge(x,y,w); addedge(y,x,w); all+=w; } dfs(1,0); printf("%lld\n",all*2-sum); } return 0; }
相关文章推荐
- POJ 1067 取石子游戏(威佐夫博弈)
- 第三方视频聊天解决----云通讯
- Java Web 网站设置session过期时间
- Android电话拦截操作
- 第三方视频聊天解决----云通讯
- Failed to start monitoring XXXXX\web.config because access was denied
- HDU 4786 Fibonacci Tree (2013ACMICPC 成都站 F) 并查集
- 知识点梳理总结(2,STRUTS1路径配置篇)
- leetcode 078 —— Subsets
- 黑马程序员——正则表达式
- iOS蓝牙4.0开发01-前期准备
- 基于VB和研华1710lL采集卡的摩擦温度采集
- javascript实现的淘宝旅行通用日历组件用法实例
- BugFree塔建
- jquery中children()、find()的区别
- stm32学习资料
- [HDU 5340] Three Palindromes 最长回文串
- python os.path模块
- jsp路径问题
- 线程的结合态和分离态